• 使用BackGroundWorker在多线程中访问Winform控件,当不是创建这个控件的线程访问控件时,把线程调整到是创建这个控件的线程去控制。,代码为红色的


    多线程访问控件在网上的方法有很多,这里只记录我用到的这个,其他的可以去网上搜索,很多。

    首先声明一个全局变量和一个委托类型(用来访问控件)


     

    01.private BackgroundWorker _bWorker;  
    02.delegate void SetProgressBarDelegate(int value);

    在一个按钮事件里面给这个workfer赋值一些属性

    01._bWorker = new BackgroundWorker();  
    02.            _bWorker.DoWork += new DoWorkEventHandler(bWorker_DoWork);  
    03.            _bWorker.WorkerReportsProgress = true;  
    04.            _bWorker.WorkerSupportsCancellation = true;  
    05.  
    06.            _bWorker.RunWorkerAsync();  
    07.            _bWorker.ProgressChanged += delegate(object s, ProgressChangedEventArgs ex)  
    08.            {  
    09.                if (proBarState.InvokeRequired)  
    10.                {  
    11.                    SetProgressBarDelegate setProgressBar = new SetProgressBarDelegate(delegate(int value)  
    12.                    {  
    13.                        proBarState.Value = ex.ProgressPercentage;  
    14.                    });  
    15.                    this.Invoke(setProgressBar);  
    16.                }  
    17.                else  
    18.                {  
    19.                    proBarState.Value = ex.ProgressPercentage;  
    20.                }  
    21.            };  
    22.            _bWorker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs ex)  
    23.            {  
    24.                  
    25.                  
    26.                if (ex.Cancelled)  
    27.                {  
    28.                    lblState.Text = "dd";  
    29.                    proBarState.Value = 0;  
    30.                }  
    31.                else  
    32.                {  
    33.                    lblState.Text = "ss";  
    34.                }  
    35.            }; 
    

      

    01.void bWorker_DoWork(object sender, DoWorkEventArgs e)  
    02.        {  
    03.              
    04.            //function to do work  
    05.            if (_bWorker.CancellationPending)  
    06.            {  
    07.                e.Cancel = true;  
    08.            }  
    09.        }  
    

      

    上面的代码最重要的部分是红字的那this.Invoke(setProgressBar);这句话的意思是winfrom应用程序的主线程(创建控件的那个线程)给控件赋值。this代表主线程。

    InvokeRequired属性查找msdn:获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。也就是说如果控件位于创建控件的线程(主线程)之外,就需要使用invoke方法将操作控件的方法推送到合适的线程(主线程)中执行。

    还有一个设置什么全局属性的(忘了,大意是不检测跨线程访问控件安全性的,那个是全局属性,一个地方设置了其他都是如此,在其他需要检测安全性的地方容易出bug),那个不可取。

  • 相关阅读:
    linux命令之free篇
    linux操作之逻辑分区与交换分区篇
    linux之软连接,硬连接篇
    Linux之磁盘分区篇
    Linux命令之vi篇
    JVM总结-垃圾回收算法
    JVM总结-字节码
    JVM总结-java对象的内存布局
    JVM-synchronized怎么实现的?
    JVM总结-invokedynamic
  • 原文地址:https://www.cnblogs.com/xiaofengfeng/p/2278136.html
Copyright © 2020-2023  润新知