All rules
CA2008Reliability Enabled by default: No

Do not create tasks without passing a TaskScheduler

Do not create tasks without passing a TaskScheduler

Microsoft docs

Description

The following .NET task creation and continuation methods have overloads that allow specifying or omitting a System.Threading.Tasks.TaskScheduler instance:

  • System.Threading.Tasks.TaskFactory.StartNew methods
  • System.Threading.Tasks.Task.ContinueWith methods

Always specify an explicit System.Threading.Tasks.TaskScheduler argument to avoid the default System.Threading.Tasks.TaskScheduler.Current value, whose behavior is defined by the caller and may vary at runtime. System.Threading.Tasks.TaskScheduler.Current returns the scheduler associated with whatever System.Threading.Tasks.Task is currently running on that thread. If there is no such task, it returns System.Threading.Tasks.TaskScheduler.Default, which represents the thread pool. Using System.Threading.Tasks.TaskScheduler.Current could lead to deadlocks or UI responsiveness issues in some situations, when it was intended to create the task on the thread pool, but instead it waits to get back onto the UI thread.

For further information and detailed examples, see New TaskCreationOptions and TaskContinuationOptions in .NET Framework 4.5. VSTHRD105 - Avoid method overloads that assume TaskScheduler.Current is a similar rule implemented in Microsoft.VisualStudio.Threading.Analyzers package.

Cause

A task creation or continuation operation uses a method overload that does not specify a System.Threading.Tasks.TaskScheduler parameter.

How to fix violations

To fix violations, call the method overload that takes a System.Threading.Tasks.TaskScheduler and explicitly pass in System.Threading.Tasks.TaskScheduler.Default or System.Threading.Tasks.TaskScheduler.Current to make the intent clear.

Example

// This code violates the rule.
var badTask = Task.Factory.StartNew(
    () =>
    {
        // ...
    }
);
badTask.ContinueWith(
    t =>
    {
        // ...
    }
);

// This code satisfies the rule.
var goodTask = Task.Factory.StartNew(
    () =>
    {
        // ...
    },
    CancellationToken.None,
    TaskCreationOptions.None,
    TaskScheduler.Default
);
goodTask.ContinueWith(
    t =>
    {
        // ...
    },
    CancellationToken.None,
    TaskContinuationOptions.None,
    TaskScheduler.Default
);

When to suppress

This warning is intended primarily for libraries, where the code may be executed in arbitrary environments and where code shouldn't make assumptions about the environment or how the caller of the method may be invoking or waiting on it. It may be appropriate to suppress the warning for projects that represent application code rather than library code.

Group results
0 yes 0 no
ConsensusNone (disabled)
Severity preference (yes voters)
Suggestion0
Warning0
Error0