Roslyn-analyzers: CA2008 Do not create tasks without passing a TaskScheduler should not appear

Created on 29 Nov 2018  路  5Comments  路  Source: dotnet/roslyn-analyzers

Analyzer package

Microsoft.CodeAnalysis.FxCopAnalyzers

Package Version

Example: v2.6.2

Diagnostic ID

CA2008: Do not create tasks without passing a TaskScheduler

Do not create tasks unless you are using one of the overloads that takes a TaskScheduler. The default is to schedule on TaskScheduler.Current, which would lead to deadlocks. Either use TaskScheduler.Default to schedule on the thread pool, or explicitly pass TaskScheduler.Current to make your intentions clear.

I could not find a documentation page.

Repro steps

public class Program
{
  public static async Task Main(string[] args)
  {
    var taskScheduler = TaskScheduler.Default;
    var taskFactory = new TaskFactory(taskScheduler);
    await taskFactory.StartNew(async () => await Task.Delay(1000)).Unwrap();
  }
}

Expected behavior

No warning is displayed as a TaskScheduler has been defined.

Actual behavior

Warning is dispalyed.


I've taken a look here and in my opinion the code doesn't make sense as StartNew on TaskFactory has no overload to specify a TaskScheduler and its defined when initializing the TaskFactory.

Area-Microsoft.NetCore.Analyzers help wanted

Most helpful comment

This is still a problem with the latest analyzer:

CA2008 does not apply to Task.Run. This method uses TaskScheduler.Default, as opposed to TaskFactory.StartNew that defaults to TaskScheduler.Current.

All 5 comments

My thoughts here:

  1. It would be nice for the analyzer to handle this specialized case where a TaskScheduler was provided to a custom TaskFactory instance, as opposed to obtaining the factory through the Task.Factory property. However, this analysis would be relatively expensive and I'm not sure how much benefit it would provide in the end.
  2. A scheduler can be provided to StartNew via this overload.
  3. The ideal way to handle this for the case of TaskScheduler.Default is to use Task.Run instead of Task.Factory.StartNew. The call is shorter, the scheduler is consistent, and it avoids the need to call Unwrap().

@sharwell Thanks for your quick answer.

1: & 2: I'll take a look if I will dig into the code of the analyzer and provide a pullrequest, if I'll just disable the warning or if I use the overload to specify the TaskScheduler everytime even if its not needed.

3: As I'm implementing library code where the user should have the possiblity to define the TaskScheduler I can't do this.

Most likely I'll use the overload you mentioned.

Should I close this issue or do you want to keep it open?

Amusingly, our version of this analyzer (VSTHRD105) got the same feedback.

This is still a problem with the latest analyzer:

c# var test = Task.Run(async () => { await Task.Delay(1000).ConfigureAwait(false); });

No warning.

Also no warning when you pass the CancellationToken and not options and a scheduler.

Whats the help-wanted label here for?

Whats the ask?

If i have time this weekend I can try to tackle it if it's medium difficultly 馃摝

This is still a problem with the latest analyzer:

CA2008 does not apply to Task.Run. This method uses TaskScheduler.Default, as opposed to TaskFactory.StartNew that defaults to TaskScheduler.Current.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

paulomorgado picture paulomorgado  路  3Comments

Grauenwolf picture Grauenwolf  路  3Comments

paulomorgado picture paulomorgado  路  3Comments

sharwell picture sharwell  路  4Comments

SixFive7 picture SixFive7  路  4Comments