《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

相关文章
相关标签/搜索