2017-05-11 49 views
1

我希望任務在50毫秒結束時完成。然後任務的狀態應設置爲「取消」,否則設置爲「RunToCompletion」。取消任務並將狀態設置爲「已取消」

任務生成是在這裏:

CancellationTokenSource cts = new CancellationTokenSource(50); 
CancellationToken ct = cts.Token; 
Task test_task = Task.Run(async() => 
{ 
    try 
    { 
     tokenS.Token.Register(() => 
     { 
      cts.Cancel(); 
      ct.ThrowIfCancellationRequested(); 
     }); 
     await NotifyDevice(BLEDevice); 
    } 
    catch (Exception e) 
    { 
    } 
},ct); 

我得到的到現在是一個AggregateException,不得到由try/catch - 阻塞莫名其妙逮住。

+0

你想要一個50ms後取消任務還是希望在50ms後取消操作? –

+0

任務「test_task」。操作是什麼意思? '等待NotifyDevice(BLEDevice)'? – Laurence

+0

據我瞭解'NotifyDevice'可以持續時間超過50ms。你希望當'test_task'在50ms後被取消(簡單解決方案)時它會繼續運行嗎? –

回答

1

以下是與您的問題類似的問題:Is it possible to cancel a C# Task without a CancellationToken?。但解決方案不會取消NotifyDevice方法中的任務。只有基礎任務支持取消,才能取消該任務。並根據文檔I​Async​Info可以取消。我將與包裝去確保,如果取消底層任務需要更多的時間的任務是在50毫秒的情況下取消:

CancellationTokenSource cts = new CancellationTokenSource(50); 
await NotifyDevice(BLEDevice, cts.Token).WithCancellation(cts.Token); 

編輯:擴展方法本身:

public static async Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken) 
{ 
    var tcs = new TaskCompletionSource<bool>(); 
    using(cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs)) 
     if (task != await Task.WhenAny(task, tcs.Task)) 
      throw new OperationCanceledException(cancellationToken); 
    return await task; 
} 
+0

很抱歉,但我不能讓這種擴展方法與我一起工作。編譯器不會認出這個方法?! – Laurence

+0

是的,你應該在你的項目中的某個地方實現它。我會更新我的答案,以便它包含它。 –

+0

沒有...編譯器似乎還有問題... – Laurence