簡體   English   中英

重新進入時取消異步方法的模式

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM