问题描述:
假设:UI线程上有一个lable一个,TextBox一个
现在从一个非UI线程调用BegionInvoke后传递一个string类型参数更新Lable,
然后又从另一个非UI线程调用BegiobInvoke后传递一个string类型和int类型参数更新TextBox,
委托就可以用一个如:
        (1) private delegate void UpdateUiHandler(string xx);
        
        (2) private delegate void UpdateUiHandlerA(int xx,int y);        --private delegate void UpdateUiHandler(params object[] pars);
是不是我必需就要写三个相对应的方法来更新UI,还是可以将(1),(2)合起来(怎么合?)再将分别的方法合起来(又怎么合)?如:
        private delegate void UpdateUiHandler(string xx);
        private delegate void UpdateUiHandlerA(string xx, int yy);        private void haha()
        {
            this.BeginInvoke(new UpdateUiHandler(xx), new object[] { "xx" });   
        }        private void hahaha()
        {
            this.BeginInvoke(new UpdateUiHandlerA(yy), new object[] { "xx", 123 });
        }        private void xx(string xx)
        {
            label1.Text = xx;
        }        private void yy(string xx, int yy)
        {
            textBox1.Text = xx;
            Process.Value = yy;
        }我的意思是更新(但是不同)很少的UI都需要写很多的委托和相应的方法,有没有统一方式一起就处理了?

解决方案 »

  1.   


    this.Invoke((MethodInvoker)delegate
    {
       //更新的代码
    });
      

  2.   

    从.net1.1延续的一种方法:
    这样设置:
    System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls = false;
    子线程可以直接访问控件。
      

  3.   

        
            private delegate void UpdateUiHandler(string xx);
            private delegate void UpdateUiHandlerA(string xx, int yy);        private void haha(string xx)
            {
                if(this.InvokeRequired )
                   this.Invoke(new UpdateUiHandler(haha), new object[]{xx});
                else
                   label1.Text = xx;
                   
            }        private void hahaha(string xx,int yy)
            {
                if(this.InvokeRequired )
                   this.Invoke(new UpdateUiHandler(hahahaha), new object[]{xx,yy});
                else
                {
                   textBox1.Text = xx;
                   Process.Value = yy;
                } 
            }        
      

  4.   

            private void hahaha(string xx,int yy)
            {
                if(this.InvokeRequired )
                   this.Invoke(new UpdateUiHandlerA(hahahaha), new object[]{xx,yy});
                else
                {
                   textBox1.Text = xx;
                   Process.Value = yy;
                } 
            }
      

  5.   

         private void button2_Click(object sender, EventArgs e)
            {
                Thread th = new Thread(new ThreadStart(threadMath1));
                th.Name = "The Thread1";
                th.Start();
                frm2.ShowDialog();
            }
            public delegate void DeleteGateCallBack(string str,DateTime time);
            public void threadMath1()
            {
                frm2.label1.Invoke(new DeleteGateCallBack(this.ChangeLableText),new object[]{Thread.CurrentThread.Name,DateTime.Now});
            }
            public void ChangeLableText(string str,DateTime time)
            {
                frm2.label1.Text = str + time.ToString();
            }
      

  6.   

    直接拖个 backgroundwork组件上去 世界就清净了
      

  7.   


    千万别省事
    否则会遇到莫名其妙的死锁问题,尤其当UI线程压力较大的时候死锁非常频繁,我在某项目里亲身体验过了
    尽量不要用Invoke,而采用BeginInvoke
    另外注意所有的Control构造时所在的线程均是在UI线程,除了该线程任何线程都不要去尝试构造Control包括其子类。
    如果需要在其他线程构造Control或者Form,必要要通过UI线程转一下的很关键
    dearymz#163.com
      

  8.   

    核心问题是,跨线程交互问题吗?如果是那么MSDN上有相关解决方案,比较分散,看一下做一下才可能会.
      

  9.   

    上面一堆高招。 
    如果多线程的话可以考虑 Mutex