zoukankan      html  css  js  c++  java
  • 多线程进度条

     #region
            //一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它
            private delegate void SetPos(int ipos);
            private void SetTextMessage(int ipos)
            {
                if (this.InvokeRequired)
                {
                    SetPos setpos = new SetPos(SetTextMessage);
                    this.Invoke(setpos, new object[] { ipos });
                }
                else
                {
                    this.label1.Text = ipos.ToString() + "/100";
                    this.prcBar.Value = Convert.ToInt32(ipos);
                }
            }
                    private void SleepT()
            {
                for (int i = 0; i < 500; i++)
                {
                    System.Threading.Thread.Sleep(100);//没什么意思,单纯的执行延时 
                    SetTextMessage(100 * i / 500);
                }
            }
        #endregion
            private void button1_Click(object sender, EventArgs e)
            {
                Thread fThread = new Thread(new ThreadStart(SleepT));//开辟一个新的线程 
                fThread.Start();
            }

    在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法,Invoke 和 BeginInvoke 就是为了解决这个问题而出现的,使你在多线程中安全的更新界面显示。

    正确的做法是将工作线程中涉及更新界面的代码封装为一个方法,通过 Invoke 或者 BeginInvoke 去调用,两者的区别就是一个导致工作线程等待,而另外一个则不会。

    而所谓的“一面响应操作,一面添加节点”永远只能是相对的,使 UI 线程的负担不至于太大而已,因为界面的正确更新始终要通过 UI 线程去做,我们要做的事情是在工作线程中包揽大部分的运算,而将对纯粹的界面更新放到 UI 线程中去做,这样也就达到了减轻 UI 线程负担的目的了。

    举个简单例子说明下使用方法,比如你在启动一个线程,在线程的方法中想更新窗体中的一个TextBox.. 
    
    using System.Threading; 
    
    //启动一个线程 
    Thread thread=new Thread(new ThreadStart(DoWork)); 
    thread.Start(); 
    
    //线程方法 
    private void DoWork() 
    { 
    this.TextBox1.Text="我是一个文本框"; 
    } 
    
    如果你像上面操作,在VS2005或2008里是会有异常的... 
    
    正确的做法是用Invoke\BeginInvoke
    
    using System.Threading;
    namespace test
    {
    public partial class Form1 : Form
    {
    public delegate void MyInvoke(string str1,string str2);
    public Form1()
    {
    InitializeComponent();
    
    
    }
    public void DoWork()
    {
    MyInvoke mi = new MyInvoke(UpdateForm);
    this.BeginInvoke(mi, new Object[] {"我是文本框","haha"});
    }
    public void UpdateForm(string param1,string parm2)
    {
    this.textBox1.Text = param1+parm2;
    }
    private void button1_Click(object sender, EventArgs e)
    {
    Thread thread = new Thread(new ThreadStart(DoWork));
    thread.Start();
    }
    }
    }
    注意代理的使用! 
  • 相关阅读:
    Java实现 LeetCode 455 分发饼干
    Java实现 LeetCode 455 分发饼干
    Java实现 LeetCode 455 分发饼干
    Java实现 LeetCode 454 四数相加 II
    Java实现 LeetCode 454 四数相加 II
    Java实现 LeetCode 454 四数相加 II
    FFmpeg解码H264及swscale缩放详解
    linux中cat more less head tail 命令区别
    C语言字符串操作总结大全(超详细)
    如何使用eclipse进行嵌入式Linux的开发
  • 原文地址:https://www.cnblogs.com/yzj1212/p/2639570.html
Copyright © 2011-2022 走看看