>
>
>
V3167. Parameter of 'CancellationToken'…


V3167. Parameter of 'CancellationToken' type is not used inside function's body.

The analyzer found an unused parameter of the 'CancellationToken' type received by the method.

Objects of this type are usually used in cases when it may be necessary to interrupt an operation in a parallel thread. A method that receives 'CancellationToken' as a parameter can access it at runtime to terminate prematurely if needed. In some cases, the token is also passed as an argument when calling other methods to allow them to terminate prematurely.

It looks suspicious when the method receives 'CancellationToken' but does not use it. Perhaps, this parameter was supposed to cancel the operation if needed. However, the parameter became redundant due to a typo. As a result, the application might not respond promptly to cancellation requests from the user.

Consider an example:

public List<SomeStruct> LoadInfo(string[] keys, CancellationToken token)
{
  List<SomeStruct> result = new List<SomeStruct>();
  
  foreach (string key in keys)
  {
    SomeStruct item = LoadHugeData(key);
    result.Add(item);
  }
  
  return result;
}

This method performs sequential loading of large amounts of data. It makes sense to implement a potential way of interrupting such an operation. Despite this, the 'token' parameter is not used. Such code looks suspicious and is highlighted by the analyzer as a potential erroneous place. Here is a possible fixed version of this code:

public List<SomeStruct> LoadInfo(string[] keys, CancellationToken token)
{
  List<SomeStruct> result = new List<SomeStruct>();
  
  foreach (string key in keys)
  {
    if(token.IsCancellationRequested)
       break;

    SomeStruct item = LoadHugeData(key);
    result.Add(item);
  }
  
  return result;
}

Sequential data download can now be interrupted. If you receive a request to cancel the operation, the 'LoadInfo' method stops loading the elements and returns what was loaded before the operation cancellation.

Look at another example:

void ExecuteQuery(CancellationToken token = default) 
{ .... }

public void ExecuteSomeActions(CancellationToken token)
{
  ....
  ExecuteQuery();
  ....
}

The 'executeQuery' method can take a value of the 'CancellationToken' type as an argument. However, when called in the 'ExecuteSomeActions' method, the 'token' parameter is not passed to the 'executeQuery' method. As a result, such code may not respond promptly to undo actions.

To fix the problem, one has to pass 'token' as an argument to the 'executeQuery' method:

ExecuteQuery(token);

Note that the analyzer will not issue warnings in cases where the method is marked with the 'override' modifier or is part of an interface implementation. This exception is due to the fact that when inheriting and overriding, the method signature must contain a parameter of the 'CancellationToken' type, regardless of whether a particular implementation provides for its use. A similar exception relates to virtual methods: the 'CancellationToken' in a declaration may not be intended for the standard implementation, but for derived classes that will override this method.

Also, the warning will not be issued for lambda expressions, since they are often used as event handlers or passed as arguments. In these cases, the function will have to receive a certain set of parameters, even in cases when the function doesn't need parameters for proper execution.