《C#併發編程經典實例》學習筆記—2.3 報告任務

問題

異步操做時,須要展現該操做的進度html

解決方案

IProgress<T> InterfaceProgress<T> Class編程

插一段話:讀《C#併發編程經典實例》這本書偶有困惑,深感書中內容過於精煉,或許是做者故意爲之,但顯然對我這般知識淺薄的人來講,讀起來這本書感到晦澀。偶然找到做者的我的博客,看到做者博客中對某一個知識點不一樣時間點上由淺至深的研究,十分欣喜。做者我的博客地址:https://blog.stephencleary.com/api

可查看此書做者博客中相關Progress的文章Reporting Progress from Async Tasks瞭解更多一手知識併發

文中做者屢次提到UI線程,很困惑,由於最近幾年基本沒在工做中寫WPF、WebForm或者WinForm,因此做者說UI線程時很困惑,將其帶入WPF、WebForm或者WinForm的使用場景,就好理解了。異步

不在廢話,上文中僞代碼例子async

static async Task MyMethodAsync(IProgress<double> progress = null)
{
    double percentComplete = 0;
    while (!done)
    {
        ...
        if (progress != null)
        progress.Report(percentComplete);
    }
}

Progress只有一個Report方法,Report報告進度更改函數

static async Task CallMyMethodAsync()
{
    var progress = new Progress<double>();
    progress.ProgressChanged += (sender, args) =>
    {
        ...
    };
    await MyMethodAsync(progress);
}

注意

  1. IProgress<T>參數能夠爲空,這意味着該異步操做不須要報告更改進度。
  2. Report方法能夠是異步的,這樣的話,MyMethodAsync執行過程當中,可能Report方法還未執行,進度尚未被更新。這樣的話,T最好是一個不可變類型,值類型最好,若是T非要使用可變類型,最好每次Copy一個副本。
  3. 若是一個方法能夠報告進度,最好也應該能夠被取消。
  4. Progress 會在建立時捕獲當前上下文,而且在這個上下文中調用回調函數。這意味着,若是在 UI 線程中建立了 Progress ,就能在 Progress 的回調函數中更新 UI,即便異步方法是在後臺線程中調用 Report 的。

關於如何使用進度,並能夠取消該方法的文章,可查看4.5 中的異步: 啓用進度和異步 Api 中的取消線程

異常

Progress<T>.ProgressChanged不會拋出異常,或者說它拋出的異常會直接拋給上下文contextcode

相關文章
相關標籤/搜索