zoukankan      html  css  js  c++  java
  • 多线程学习笔记(二) BackgroundWorker 和 ProgressChanged

    BackgroundWorker是在内部使用了线程池的技术;同时,在Winform 或WPF编码中,它还给工作线程和UI线程提供了交互的能力。

    Thread和ThreadPool默认都没有提供这种交互能 力,而BackgroundWorker却通过事件提供了这种能力。这种能力包括:报告进度、支持完成回调、取消任务、暂停任务等。

    一般而言,无特殊需要的,优先考虑使用标准的backgroundworker
    再加上线程池,多数问题都能应付了
    只有特别需要精确控制或性能的才用thread

    BackgroundWorker会在主线程之外,另开一个后台线程,

    我们可以把一些处理放在后台线程中处理,完成之后,后台线程会把结果传递给主线程,同时结束自己。

    如果要显示进度,比如我们希望走马灯式更新label,就要把 bw.WorkerReportsProgress = true;

    如果要支持中途取消, 则把bw.WorkerSupportsCancellation = true; 

            private void button3_Click(object sender, EventArgs e)
            {
                using (BackgroundWorker bw = new BackgroundWorker())
                {
                    bw.WorkerReportsProgress = true;
                    bw.ProgressChanged += bw_ProgressChanged;
                    bw.RunWorkerCompleted += bw_RunWorkerCompleted;
                    bw.DoWork += bw_DoWork;
    
                    //允许用户指定显示数据的范围呢!所以需要把100作为参数传递给计算过程
                    bw.RunWorkerAsync(100); 
                }
    
            }
            //这时返回了主线程,所以可以直接使用UI控件了
            void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                //修改进度条的显示。
                //this.progressBarSum.Value = e.ProgressPercentage;
    
                //如果有更多的信息需要传递,可以使用 e.UserState 传递一个自定义的类型。
                //这是一个 object 类型的对象,您可以通过它传递任何类型。
                //我们仅把当前 sum 的值通过 e.UserState 传回,并通过显示在窗口上。
                string message = e.UserState.ToString();
                label1.Text = message;
            }
            //e.Argument=bw.RunWorkerAsync("Hello World")的参数
            void bw_DoWork(object sender, DoWorkEventArgs e)
            {
                System.Diagnostics.Debug.WriteLine("bw_DoWork");
                BackgroundWorker bgWorker = sender as BackgroundWorker;
                //这里的操作是在另一个线程上完成的,不应该操作UI
                //在这里执行耗时的运算。
    
                int endNumber = 0;
                if (e.Argument != null)
                {
                    endNumber = (int)e.Argument;
                }
    
                for (int i = 0; i <= endNumber; i++)
                {
                    bgWorker.ReportProgress(i, "current num:" + i.ToString());
                    Thread.Sleep(50); //为了方便演示
                }
                
            }
            //这时后台线程已经完成,并返回了主线程,所以可以直接使用UI控件了
            void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                System.Diagnostics.Debug.WriteLine("bw_RunWorkerCompleted");
                if (e.Error == null)
                    lblMsg.Text = "正常结束";
                else
                    lblMsg.Text = "异常结束"+ e.Error.Message;
            }

    参考: https://www.cnblogs.com/sparkdev/p/5906272.html

    https://www.cnblogs.com/luminji/archive/2011/05/13/2044801.html

    https://www.cnblogs.com/happy555/archive/2007/11/07/952315.html

    https://www.cnblogs.com/grenet/archive/2011/12/21/2289014.html

    我所知道的.NET异步  https://www.cnblogs.com/scy251147/archive/2012/03/03/2378477.html

    支持暂停操作的Backgroundworker  https://www.cnblogs.com/chenxizhang/archive/2010/03/13/1685209.html

  • 相关阅读:
    Kubernetes+Federation打造跨多云管理服务
    idou老师教你学istio 31:Istio-proxy的report流程
    《软件工程》课程总结(补)
    《软件工程》课程总结
    十二周# 学习进度总结
    十一周# 学习进度总结
    十周# 学习进度总结
    九周# 学习进度总结
    八周# 学习进度总结
    团队项目——编写项目的Spec
  • 原文地址:https://www.cnblogs.com/zitjubiz/p/11532501.html
Copyright © 2011-2022 走看看