C# 为什么任务在主线程中运行?

C# 为什么任务在主线程中运行?,c#,task,C#,Task,我编写了自定义TaskScheduler: public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler { private BlockingCollection<Task> _tasks = new BlockingCollection<Task>(); private List<Thread> _threads; private bool work = true

我编写了自定义TaskScheduler:

public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
{

    private BlockingCollection<Task> _tasks = new BlockingCollection<Task>();
    private List<Thread> _threads;
    private bool work = true;

    public LimitedConcurrencyLevelTaskScheduler(int maxConcurrencyLevel)
    {

        _threads = new List<Thread>();
        for (int i = 0; i < maxConcurrencyLevel; i++)
        {
            _threads.Add(new Thread(() =>
                                        {
                                            while (work)
                                            {
                                                TryExecuteTask(_tasks.Take());
                                            }
                                        }) { IsBackground = true, Name = "TaskShedulerThread#" + i });
        }
        foreach (var thread in _threads)
        {
            thread.Start();
        }

    }

    protected override void QueueTask(Task task)
    {
        _tasks.Add(task);
    }

    protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
    {
        return !_threads.Contains(Thread.CurrentThread) && TryExecuteTask(task);
    }

    public override int MaximumConcurrencyLevel { get { return 1; } }

    protected override IEnumerable<Task> GetScheduledTasks()
    {
        return _tasks.ToArray();
    }

    public void Dispose()
    {
        if (_threads != null)
        {
            _tasks.CompleteAdding();
            work = false;

            _tasks.Dispose();
            _tasks = null;
            _threads = null;
        }
    }
}

为什么我的任务在主线程中运行?

由于TPL特性,任务在主线程上执行。当线程对尚未开始执行的任务调用
WaitAll
(或任何类似方法)时,TPL可允许所述线程尝试执行挂起的任务本身,而不是阻塞,直到任务调度器的工作线程之一执行为止

可以通过重写任务调度器的
TryExecuteTaskInline
方法来控制此行为,禁止它执行任何任务,除非当前线程恰好是工作线程

protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
    return !_threads.Contains(Thread.CurrentThread) && TryExecuteTask(task);
}
在您的实现中,只需在
包含
检查之前删除否定:

protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
    return _threads.Contains(Thread.CurrentThread) && TryExecuteTask(task);
}
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
    return !_threads.Contains(Thread.CurrentThread) && TryExecuteTask(task);
}
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
    return _threads.Contains(Thread.CurrentThread) && TryExecuteTask(task);
}