所以我有樣品試了一下: - (?但是這是保證)
var continuations = new List<Task>();
for (int i = 0; i < 20; i++) {
int counter = i;
var continuation = Task.Run(() => {
Console.WriteLine($"T{counter}: Start.");
Thread.Sleep(500);
Console.WriteLine($"T{counter}: Complete.");
}).ContinueWith(t => {
Console.WriteLine($"C{counter}: Start.");
Thread.Sleep(50);
Console.WriteLine($"C{counter}: Complete.");
});
continuations.Add(continuation);
}
Task.WaitAll(continuations.ToArray());
,它輸出以下暗示調度程序在啓動一個新的任務的延續優先:
T1: Start.
T2: Start.
T3: Start.
T0: Start.
T1: Complete.
T2: Complete.
T3: Complete.
C1: Start.
C3: Start.
T0: Complete.
C0: Start.
C2: Start.
C1: Complete.
T4: Start.
C3: Complete.
T5: Start.
C0: Complete.
T6: Start.
C2: Complete.
T7: Start.
T4: Complete.
C4: Start.
T5: Complete.
C5: Start.
T6: Complete.
C6: Start.
T7: Complete.
C7: Start.
C4: Complete.
C5: Complete.
T9: Start.
T8: Start.
C7: Complete.
T10: Start.
C6: Complete.
T11: Start.
T8: Complete.
C8: Start.
T9: Complete.
C9: Start.
T11: Complete.
C11: Start.
T10: Complete.
C10: Start.
C9: Complete.
C8: Complete.
T13: Start.
T12: Start.
C11: Complete.
T14: Start.
C10: Complete.
變化。這裏在啓動Task和註冊Continuation之間在調用線程上有額外的執行。
var continuations = new List<Task>();
for (int i = 0; i < 20; i++) {
int counter = i;
var task = Task.Run(() => {
Console.WriteLine($"T{counter}: Start.");
Thread.Sleep(500);
Console.WriteLine($"T{counter}: Complete.");
});
Thread.Sleep(100); // Do some stuff before registering continuation.
var continuation = task.ContinueWith(t => {
Console.WriteLine($"C{counter}: Start.");
Thread.Sleep(150);
Console.WriteLine($"C{counter}: Complete.");
});
continuations.Add(continuation);
}
Task.WaitAll(continuations.ToArray());
結果與上述情況相同,即對任務N的連續性給予其他排隊任務的優先級。
T0: Start.
T1: Start.
T2: Start.
T3: Start.
T0: Complete.
C0: Start.
T1: Complete.
C1: Start.
C0: Complete.
T4: Start.
T2: Complete.
C2: Start.
C1: Complete.
T5: Start.
T3: Complete.
C3: Start.
C2: Complete.
T6: Start.
C3: Complete.
T7: Start.
T4: Complete.
C4: Start.
T5: Complete.
C5: Start.
C4: Complete.
T8: Start.
T6: Complete.
C6: Start.
C5: Complete.
T9: Start.
T7: Complete.
C7: Start.
C6: Complete.
T10: Start.
C7: Complete.
T11: Start.
T8: Complete.
C8: Start.
T9: Complete.
C9: Start.
C8: Complete.
T12: Start.
T10: Complete.
C10: Start.
C9: Complete.
T13: Start.
T11: Complete.
C11: Start.
T14: Start.
C10: Complete.
T15: Start.
C11: Complete.
T16: Start.
T12: Complete.
C12: Start.
T13: Complete.
C13: Start.
T14: Complete.
C14: Start.
C12: Complete.
T17: Start.
T15: Complete.
C15: Start.......
另一種變化。這裏所有的任務都先在Scheuler上排隊(並且可以預定運行),然後再註冊延續。
const int taskCount = 20;
var tasks = new List<Task>();
for (int i = 0; i < taskCount; i++) {
int counter = i;
var task = Task.Run(() => {
Console.WriteLine($"T{counter}: Start.");
Thread.Sleep(500);
Console.WriteLine($"T{counter}: Complete.");
});
tasks.Add(task);
}
Thread.Sleep(400);
var continuations = new List<Task>();
for (int i = 0; i < taskCount; i++) {
int counter = i;
var continuation = tasks[i].ContinueWith(t => {
Console.WriteLine($"C{counter}: Start.");
Thread.Sleep(150);
Console.WriteLine($"C{counter}: Complete.");
});
continuations.Add(continuation);
}
Task.WaitAll(continuations.ToArray());
結果與以前一樣 - 延續得到優先。
T0: Start.
T2: Start.
T3: Start.
T1: Start.
T1: Complete.
T3: Complete.
T0: Complete.
T2: Complete.
C2: Start.
C0: Start.
C3: Start.
C1: Start.
C2: Complete.
C1: Complete.
C0: Complete.
C3: Complete.
T7: Start.
T4: Start.
T6: Start.
T5: Start.
T6: Complete.
T5: Complete.
T7: Complete.
T4: Complete.
C6: Start.
C5: Start.
C7: Start.
C4: Start.
C7: Complete.
T8: Start.
C5: Complete.
T9: Start.
C6: Complete.
T10: Start.
C4: Complete.
T11: Start.
T8: Complete.
C8: Start.
T10: Complete.
C10: Start.
T9: Complete.
C9: Start.
T11: Complete.
C11: Start.
C8: Complete.
T12: Start.
C9: Complete.
T13: Start.
C10: Complete.
T14: Start.
C11: Complete.
T15: Start.
T14: Complete.
T12: Complete.
C12: Start.
T13: Complete.
C13: Start.
C14: Start.
T15: Complete.
C15: Start.
T16: Start.
C12: Complete.
C13: Complete.
T18: Start.
T17: Start.
C14: Complete.
T19: Start.
C15: Complete.
T16: Complete.
C16: Start.
T18: Complete.
C18: Start.
T17: Complete.
T19: Complete.
C19: Start.
C16: Complete.
C17: Start.
C18: Complete.
C19: Complete.
C17: Complete.
哪個調度程序?你知道你可以實現你自己的?你的意思是默認的調度程序? – TomTom
@TomTom問題已澄清。 – Ricibob
看起來愚蠢的高度依賴於調度程序對任務的任何排序,除了通過延續執行並通過命令「await」執行的排序。我很想明確說明*不,這是不能保證的,因爲它會給實施帶來不必要的負擔,隨時都會受到束縛*,但是因爲我不是微軟的員工,所以我覺得不舒服這樣做。一般來說,儘管如此:在一個平行的詞中,如果你沒有同步事物,那麼事情就不會同步,除了偶然事件。 –