Skip to content

NullReferenceException when Task is Start-ed and Wait-ed concurrently #119484

@chris-white-wtw

Description

@chris-white-wtw

Description

I encountered a NullReferenceException thrown from within System.Threading.Tasks.Task.ScheduleAndStart as it was executing a Task generated by a Parallel.For call.

It appears to be due to simultaneous calls to the Start and Wait methods on the task, from different threads.

The exception is thrown by some event logging code, and so only happens if TPL task events are enabled.

Reproduction Steps

The following console app reliably reproduces the exception when run under Visual Studio debugger:

var scheduler = new ConcurrentExclusiveSchedulerPair().ConcurrentScheduler;

bool stop = false;
Task? taskField = null;

var waitTask = new Task(() =>
{
  while (!stop)
  {
    taskField?.Wait();
  }
});

waitTask.Start(scheduler);

while (!Console.KeyAvailable)
{
  taskField = new Task(() => { });
  taskField.Start(scheduler);
}

stop = true;

I have also reproduced it by running the program outside the debugger and then starting a PerfView collection with TPL task events enabled.

Expected behavior

The above code should execute without error until the user terminates it with a keypress.

Actual behavior

A NullReferenceException is thrown:

System.ArgumentNullException
  HResult=0x80004003
  Message=Value cannot be null. (Parameter '@delegate')
  Source=System.Private.CoreLib
  StackTrace:
   at System.ArgumentNullException.Throw(String paramName)
   at System.Diagnostics.DiagnosticMethodInfo.Create(Delegate delegate)
   at System.Threading.Tasks.LoggingExtensions.GetMethodName(Delegate delegate)
   at System.Threading.Tasks.Task.ScheduleAndStart(Boolean needsProtection)
   at Program.<Main>$(String[] args) in C:\git\TaskNRE\TaskNRE\Program.cs:line 19

Regression?

I don't think so - it's reproducible in previous .NET versions and in .NET Framework 4.7.2.

Known Workarounds

No response

Configuration

.NET 9.0.8 (but happens in the two other versions I tried)
Windows 11 Enterprise Version 10.0.22631 Build 22631
x64

Other information

The exception is thrown from this line:

TplEventSource.Log.TraceOperationBegin(this.Id, "Task: " + m_action.GetMethodName(), 0);

m_action is null. Note the Debug.Assert in the previous line that m_action is not null.

I hypothesise that the call to Wait on a separate thread has caused the task to be executed to completion inline, at which point the m_action field is set to null.

It is not clear to me if there are any consequences to this if TPL logging is turned off.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions