[英]Cancel Task in async void
嗨,我有一個列表框 每當用戶選擇一個項目時,就會向網絡發送一個請求 現在我想在用戶選擇該項目時取消之前的操作,然后開始新的操作。
我使用以下代碼來做到這一點,我想知道這些代碼是否工作正常。 還是我應該嘗試另一種方式?
private CancellationTokenSource ts = new CancellationTokenSource();
private async void Subf2mCore(CancellationToken ct)
{
HtmlDocument doc = await web.LoadFromWebAsync(url);
...
foreach (var node in doc)
{
if (!ct.IsCancellationRequested)
{
....
}
}
}
我以這種方式運行 func
ts?.Cancel();
ts = new CancellationTokenSource();
Subf2mCore(ts.Token);
從技術上講,您可以這樣說,但是請注意:您觸發並忘記了,讓調用者返回Task
以了解Subf2mCore
是否已完成、失敗或取消:
private async Task Subf2mCore(CancellationToken ct)
{
HtmlDocument doc = await web.LoadFromWebAsync(url);
...
foreach (var node in doc)
{
// Often we cancel by throwing exception:
// it's easy to detect that the task is cancelled by catching this exception
// ct.ThrowIfCancellationRequested();
// You prefer to cancel manually:
// your cancellation can be silent (no exceptions) but it'll be
// difficult for caller to detect if task completed or not
// (partially completed and cancelled)
if (!ct.IsCancellationRequested)
{
....
}
}
}
// If we don't want to cancel
private async Task Subf2mCore() => Subf2mCore(CancellationToken.None);
用法:不要忘記Dispose
CancellationTokenSource
實例:
using (CancellationTokenSource ts = new CancellationTokenSource()) {
...
await Subf2mCore(ts.Token);
...
}
編輯:如果你想從外面取消:
private CancellationTokenSource ts = null;
...
using (CancellationTokenSource _ts = new CancellationTokenSource()) {
// previous task (if any) cancellation
if (null != ts)
ts.Cancel();
// let cancel from outside
ts = _ts;
try {
...
await Subf2mCore(_ts.Token);
...
}
finally {
// task completed, we can't cancel it any more
ts = null;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.