我正在嘗試構建一種可以按順序運行若干任務的調度程序(這可能不是相關術語)。C#6正在等待完成任務和所有子任務
這裏是我的POC代碼(請忽略隊列/出列機制較差,但不是這裏的問題,我猜)
編輯:感謝的@Theraot
static void Main(string[] args)
{
ProcessingQueue o_q = new ProcessingQueue();
o_q.Enqueue(async() => { await SimulateTaskSequence(1); });
o_q.Enqueue(async() => { await SimulateTaskSequence(2); });
Console.ReadLine();
}
public static async Task SimulateTaskSequence(int taskNbr)
{
Console.WriteLine("T{0} - Working 1sec", taskNbr);
Thread.Sleep(1000);
Console.WriteLine("T{0} - Zzz 1st 1sec", taskNbr);
await Task.Delay(1000);
Console.WriteLine("T{0} - Working 1sec", taskNbr);
Thread.Sleep(1000);
Console.WriteLine("T{0} - Done", taskNbr);
}
public class ProcessingQueue
{
Queue<Action> _Queue = new Queue<Action>();
private bool _stillRunning = false;
public void Enqueue(Action a)
{
lock (_Queue)
{
_Queue.Enqueue(a);
if (_stillRunning == false)
{
StartProcessing();
}
}
}
private void StartProcessing()
{
_stillRunning = true;
Task.Run(async() =>
{
Action a = null;
while (true)
{
lock (_Queue)
{
if (_Queue.Any() == true)
{
a = _Queue.Dequeue();
}
else
{
break;
}
}
await Task.Run(a); //how to wait for all subtasks!!???
}
_stillRunning = false;
});
}
我的問題的幫助一旦第一個任務(T1)的第一個等待發生,第二個任務(T2)開始執行。
我得到以下輸出:
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
我明白爲什麼這是默認的行爲,但我需要改變。我在一個新的TaskFactory中玩耍TaskContinuationOptions和TaskCreationOptions,但沒有更好的結果。 這甚至可能嗎?
非常感謝 克里斯托夫
您的ProcessingQueue類已經存在於框架中,它是ThreadPool。很難正確替換,並且它不會執行ThreadPool不做的任何操作。除了等待和即時出錯。不要這樣做。 –
@HansPassant OP所需要的與ThreadPool不同,OP需要添加的任務按順序完成。在ThreadPool中,你沒有這樣的保證,實際上ThreadPool的想法是使用多個線程並行運行(編輯:並重用線程)。現在,可以通過同步運行這些任務來實現,或者通過使用Thread來等待的其他方式來實現... OP不需要任何這些任務。 – Theraot
Task類組合得非常好,他所需要的只是ContinueWith對主任務和WaitAll進行排序,以等待子任務完成。簡單易用,但是當你發明自己的線程池時很難看清楚。 –