Skip to content

Task.Run randomly fails when using ExecutionContext.SuppressFlow  #76297

@davhdavh

Description

@davhdavh

Description

TaskScheduler.TryRunInline does not take into account if ExecutionContext.SuppressFlow is in effect.

Reproduction Steps

Helper.Set("1");

for (int i = 0; i < 10000; i++)
{
   await Task.Run(Execute);
}

static void Execute()
{
   var suppressFlow = ExecutionContext.SuppressFlow();
   var startNew = Task.Factory.StartNew(() =>
      {
         if (Helper.Get() is { } v) throw new(v);
      }
   );
   startNew.GetAwaiter().GetResult();
   suppressFlow.Undo();
}

static class Helper
{
   private static readonly AsyncLocal<string?> _asyncLocal = new();

   public static string? Get() => _asyncLocal.Value;
   public static void Set(string? s) => _asyncLocal.Value = s;
}

Expected behavior

No exceptions

Actual behavior

Randomly throws depending on TaskSchedulers mood.

Regression?

No, but it is more broken in .NET Framework

Known Workarounds

Setting TaskCreationOptions.PreferFairness or TaskCreationOptions.LongRunning prevents the problem, but requires Developer knowledge that any task is executed in suppression.

Configuration

tried on .NET Framework 4.8 & .NET 6/7

Other information

.NET Framework 4.8 will almost certainly fail on first run.
.NET 6/7 will fail within 10-20 runs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-System.Threading.TasksquestionAnswer questions and provide assistance, not an issue with source code or documentation.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions