问题描述
当前任务调度程序是否作为执行上下文流的一部分流入ThreadPool.QueueUserWorkItem
回调中?
我希望不会,因此下面的调试断言应该通过。我在网上找不到任何确认。
var scheduler = new CustomTaskScheduler();
await Task.Factory.StartNew(async () =>
{
Debug.Assert(TaskScheduler.Current == scheduler);
var tcs = new taskcompletionsource<bool>();
ThreadPool.QueueUserWorkItem(_ =>
{
Debug.Assert(TaskScheduler.Current != scheduler);
Debug.Assert(TaskScheduler.Current == TaskScheduler.Default);
tcs.SetResult(true);
});
await tcs.Task;
Debug.Assert(TaskScheduler.Current == scheduler);
},CancellationToken.None,TaskCreationoptions.None,scheduler).Unwrap();
解决方法
当前任务调度程序是否作为执行上下文流的一部分流入
ThreadPool.QueueUserWorkItem
回调中?
对我未来的自我:不,不是,正如预期的那样。这是一个简单的CustomTaskScheduler
来测试相关代码:
public class CustomTaskScheduler : TaskScheduler
{
protected override IEnumerable<Task>? GetScheduledTasks()
{
throw new NotImplementedException();
}
protected override void QueueTask(Task task)
{
ThreadPool.QueueUserWorkItem(t =>
base.TryExecuteTask((Task)t!),task);
}
protected override bool TryExecuteTaskInline(Task task,bool taskWasPreviouslyQueued)
{
return false;
}
}
在ThreadPool.QueueUserWorkItem
回调中,当前的任务调度程序确实设置回了TaskScheduler.Default
:
var scheduler = new CustomTaskScheduler();
await Task.Factory.StartNew(async () =>
{
Debug.Assert(TaskScheduler.Current == scheduler);
var tcs = new TaskCompletionSource<bool>();
ThreadPool.QueueUserWorkItem(_ =>
{
Debug.Assert(TaskScheduler.Current != scheduler);
Debug.Assert(TaskScheduler.Current == TaskScheduler.Default);
tcs.SetResult(true);
});
await tcs.Task;
Debug.Assert(TaskScheduler.Current == scheduler);
},CancellationToken.None,TaskCreationOptions.None,scheduler).Unwrap();