Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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
.net C#6等待任务和所有子任务的完全完成_.net_Multithreading_Asynchronous_Task_Taskscheduler - Fatal编程技术网

.net C#6等待任务和所有子任务的完全完成

.net C#6等待任务和所有子任务的完全完成,.net,multithreading,asynchronous,task,taskscheduler,.net,Multithreading,Asynchronous,Task,Taskscheduler,我正在尝试建立一种调度器(这可能不是相关术语),它将按顺序运行许多任务 这是我的POC代码(请忽略队列/出列机制很差,但我想这不是问题所在) 编辑:多亏了 但我期待的是: T1 - Working 1sec T1 - Zzz 1st 1sec T1 - Working 1sec T1 - Done T2 - Working 1sec T2 - Zzz 1st 1sec T2 - Working 1sec T2 - Done 我理解为什么这是默认行为,但我需要改变这一点。我在一个新的TaskFa

我正在尝试建立一种调度器(这可能不是相关术语),它将按顺序运行许多任务

这是我的POC代码(请忽略队列/出列机制很差,但我想这不是问题所在)

编辑:多亏了

但我期待的是:

T1 - Working 1sec
T1 - Zzz 1st 1sec
T1 - Working 1sec
T1 - Done
T2 - Working 1sec
T2 - Zzz 1st 1sec
T2 - Working 1sec
T2 - Done
我理解为什么这是默认行为,但我需要改变这一点。我在一个新的TaskFactory中玩TaskContinuationOptions和TaskCreationOptions,但没有更好的结果。 这可能吗

非常感谢
Christophe

我建议创建一个
ProcessingQueue
而不是
ProcessingQueue


您正在执行
Task.Run(Action Action)
,因为Action可能包含异步任务,
Run
方法不会等待任务,因为没有任务。当您调用
Task.Run(Func Task)
Run
方法知道它是任务,它将等待它时,

您的ProcessingQueue类在框架中已经存在,它是ThreadPool。很难正确替换,而且它没有做ThreadPool没有做的任何事情。除了等待,这很快就出了问题。不要这样做。@HansPassant OP想要的与线程池不同,OP希望添加的任务按顺序完成。在线程池上,您没有这样的保证,事实上,线程池的思想是使用多个线程并行运行(当然,编辑和重用线程)。现在,这可以通过同步运行这些任务来完成,或者通过使用线程等待的其他方式来完成。。。OP也不想要这些。任务类的合成非常好,他所需要的只是继续对主任务排序,并等待所有子任务完成。很简单,但当你发明自己的线程池时,这就很难看到了。
T1 - Working 1sec
T1 - Zzz 1st 1sec
T2 - Working 1sec
T2 - Zzz 1st 1sec
T1 - Working 1sec
T1 - Done
T2 - Working 1sec
T2 - Done
T1 - Working 1sec
T1 - Zzz 1st 1sec
T1 - Working 1sec
T1 - Done
T2 - Working 1sec
T2 - Zzz 1st 1sec
T2 - Working 1sec
T2 - Done
public class ProcessingQueue
{
    Queue<Func<Task>> _Queue = new Queue<Func<Task>>();

    private bool _stillRunning = false;

    public void Enqueue(Func<Task> a)
    {
        lock (_Queue)
        {
            _Queue.Enqueue(a);

            if (_stillRunning == false)
            {
                StartProcessing();
            }
        }
    }

    private void StartProcessing()
    {
        _stillRunning = true;

        Task.Run(async () =>
        {
            Func<Task> a = null;

            while (true)
            {
                lock (_Queue)
                {
                    if (_Queue.Any() == true)
                    {
                        a = _Queue.Dequeue();
                    }
                    else
                    {
                        break;
                    }
                }

                await a(); //how to wait for all subtasks!!???
            }
            _stillRunning = false;
        });
    }
Action a;
...
await Task.Run(a);