欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

《C#并发编程经典实例》学习笔记—2.3 报告任务

程序员文章站 2022-03-09 13:46:31
问题 异步操作时,需要展示该操作的进度 解决方案 " " 和 " " 插一段话:读《C 并发编程经典实例》这本书偶有困惑,深感书中内容过于精炼,或许是作者故意为之,但显然对我这般知识浅薄的人来说,读起来这本书感到晦涩。偶然找到作者的个人博客,看到作者博客中对某一个知识点不同时间点上由浅至深的研究,十 ......

问题

异步操作时,需要展示该操作的进度

解决方案

iprogress<t> interfaceprogress<t> class

插一段话:读《c#并发编程经典实例》这本书偶有困惑,深感书中内容过于精炼,或许是作者故意为之,但显然对我这般知识浅薄的人来说,读起来这本书感到晦涩。偶然找到作者的个人博客,看到作者博客中对某一个知识点不同时间点上由浅至深的研究,十分欣喜。作者个人博客地址:

可查看此书作者博客中相关progress的文章reporting progress from async tasks了解更多一手知识

文中作者多次提到ui线程,很困惑,因为最近几年基本没在工作中写wpf、webform或者winform,所以作者说ui线程时很困惑,将其带入wpf、webform或者winform的使用场景,就好理解了。

不在废话,上文中伪代码例子

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不会抛出异常,或者说它抛出的异常会直接抛给上下文context