Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当前任务计划程序是否流入ThreadPool.QueueUserWorkItem回调?_C#_.net_.net Core_Async Await_Task Parallel Library - Fatal编程技术网

C# 当前任务计划程序是否流入ThreadPool.QueueUserWorkItem回调?

C# 当前任务计划程序是否流入ThreadPool.QueueUserWorkItem回调?,c#,.net,.net-core,async-await,task-parallel-library,C#,.net,.net Core,Async Await,Task Parallel Library,当前任务计划程序是否作为执行上下文流的一部分流入ThreadPool.QueueUserWorkItem回调 我希望它不会,因此应该传递以下调试断言。我在网上找不到任何证实 var scheduler = new CustomTaskScheduler(); await Task.Factory.StartNew(async () => { Debug.Assert(TaskScheduler.Current == scheduler); var tcs = new Ta

当前任务计划程序是否作为执行上下文流的一部分流入
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();

var调度器=新建CustomTaskScheduler();
等待Task.Factory.StartNew(异步()=>
{
Assert(TaskScheduler.Current==scheduler);
var tcs=new TaskCompletionSource();
ThreadPool.QueueUserWorkItem(=>
{
Assert(TaskScheduler.Current!=调度程序);
Assert(TaskScheduler.Current==TaskScheduler.Default);
tcs.SetResult(真);
});
等待tcs任务;
Assert(TaskScheduler.Current==scheduler);
},
取消令牌。无,
任务创建选项。无,
调度器)。展开();
当前任务计划程序是否作为执行上下文流的一部分流入
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;
    }
}


QueueUserWorkItem
queues处理线程池中的下一个可用线程,该线程池由默认任务计划程序管理。如果您想使用自定义TaskScheduler,那么这是使用
StartNew
的少数有效原因之一@MichaelRandall,实际上我不想使用自定义任务调度程序。相反,我希望确保当当前环境任务调度器为非默认值时,如果使用
QueueUserWorkItem
/
UnsafeQueueUserWorkItem
,我将返回默认值。因此,现有的行为正是我所需要的。@MichaelRandall,除此之外,它很可能位于
ThreadPool
线程上,并且仍然具有
TaskScheduler.Current!=TaskScheduler.Default
。是的,我同意您可以在任何线程上设置当前任务计划程序,如果您不能设置,这将是非常有限的。我的观点是,
ThreadPool.QueueUserWorkItem
和许多其他TPL方法都会出现这种行为,除非它们特别允许您设置调度程序,或者具有其他高级选项。我个人认为问题和答案都很好,而且很多信息(正如stephen toub(意译)曾经说过的)就像空气一样,你通常不必担心它。。。直到你do@MichaelRandall,同意。我认为这是一个合理的假设,但我真的想验证一下:)这样做比深入研究更简单。
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();