我正在設計一個API,公開一個可取消的Task
,並且想確保我已經正確地設計了它。是否有暴露Task
s的標準模式(可能類似於APM BeginXxx/EndXxx模式)?任何改善建議?請參閱MyAPI.Run
公開一個可取消的任務
是否Test2
演示了並行運行多個MyAPI.Run
任務的最佳方式?
public static class MyAPI
{
public static Task<MyResult> Run(CancellationToken token) {
// lazily create Task, so as to include the specified CancellationToken
return new Task<MyResult>(MyPrivateAsyncMethod, token, token);
}
private static MyResult MyPrivateAsyncMethod(object state) {
CancellationToken ct = (CancellationToken)state;
ct.ThrowIfCancellationRequested();
return new MyResult();
}
}
public static class TestMyAPI
{
// User can start the Task directly
public static void Test1() {
CancellationTokenSource cts = new CancellationTokenSource();
MyAPI.Run(cts.Token)
.ContinueWith(task => Console.WriteLine(task.Result.ToString()))
.Start();
}
// User must wrap in new Tasks to get Parent/Child relationship
public static void Test2() {
CancellationTokenSource cts = new CancellationTokenSource();
Task.Factory.StartNew(() =>
{
var childTasks = new[] {
Task.Factory.StartNew<MyResult>(() => MyAPI.Run(cts.Token).Result, cts.Token, TaskCreationOptions.AttachedToParent, TaskScheduler.Default),
Task.Factory.StartNew<MyResult>(() => MyAPI.Run(cts.Token).Result, cts.Token, TaskCreationOptions.AttachedToParent, TaskScheduler.Default)
};
Task.Factory
.ContinueWhenAll<MyResult>(childTasks, tasks => { foreach(var task in tasks) task.ToString(); })
.Start();
}, cts.Token);
}
}
關於你的Test2重寫,會發生什麼異常處理?具體來說,通過父母/孩子的安排,我會'嘗試'父母並且抓住子女拋出的任何東西的'AggergateException'。這將如何工作在你的重寫? – nmarler
@nmarler你必須在繼續處理它 - 你可以明確地將一個Try/catch包圍在一個調用中,以便繼續處理錯誤,如果需要的話。 –
我正在考慮只返回'熱'任務的概念。在我的應用程序中,我有一個「SequenceManager」對象,負責運行其他類中的一些任務。當SequenceManager被初始化時,我的意圖是以某種安排(某些順序相互連接,某些異步)組成任務子對象任務。然後,在將來的某個時刻,可以運行這個「主」任務。我認爲現在應該簡化SequenceManager init,而是暴露一個RunAsync方法,它將即時組成子RunAsyncs。謝謝,你的建議是非常有幫助的 – nmarler