[英]Pattern for cancel async method on reentry
我想在重入時取消異步 function,這樣工作就不會堆積起來並防止不需要的工作。 例如,我的文件掃描最多需要 8 秒,但是當我在 UI 中更改文件夾時,應該取消舊的 function。 我看到了帶有CancellationToken
的示例,但在我看來代碼太多了。
我的方法是這樣的,它似乎有效,但它給代碼增加了很多混亂。 也許我也錯過了捕獲會添加更多代碼的TaskCanceledException
。
private CancellationTokenSource scanFilesState;
private IList<FileInfo> files;
private async Task ScanFilesAsync(string path)
{
// stop old running
this.scanFilesState?.Cancel();
this.scanFilesState?.Dispose();
this.scanFilesState = new CancellationTokenSource();
this.files = await FileHandler.ScanFilesAsync(path, this.scanFilesState.Token);
this.scanFilesState?.Dispose();
this.scanFilesState = null;
}
有沒有更短或更好的方法?
是否有封裝此代碼的模式?
我似乎不需要之后的清理,並提出了這種方法並包裝了 CancellationTokenSource 以確保處理安全。
public class SafeCancellationTokenSource : IDisposable
{
private CancellationTokenSource state = new CancellationTokenSource();
public CancellationTokenSource State => state;
public CancellationToken Token => State.Token;
public bool IsCancellationRequested => State.IsCancellationRequested;
public void Cancel()
{
this.state?.Cancel();
this.state?.Dispose();
this.state = new CancellationTokenSource();
}
public void Dispose()
{
this.state?.Dispose();
this.state = null;
}
}
代碼現在看起來像這樣
private SafeCancellationTokenSource scanFilesState = new SafeCancellationTokenSource();
private IList<FileInfo> files;
private async Task ScanFilesAsync(string path)
{
this.scanFilesState.Cancel();
this.files = await FileHandler.ScanFilesAsync(path, this.scanFilesState.Token);
}
編輯:再次添加對 Dispose() 的調用
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.