跨线程修改UI控件

1.直接修改, 失败引发异常.

namespace Test
{
    public partial class frmVisitControl : Form
    {
        public frmVisitControl()
        {
            InitializeComponent();
        
        }       

        private void SetLabelText()
        {
            label1.Text = "Hello";
        }
      
        private void btnVisitLabel_Click(object sender, EventArgs e)
        {
            //以下这句将引发InvalidOperationException
            Thread th = new Thread(SetLabelText);
          
            th.Start();
        }
    }
}

 

2.使用代理, 调用UI控件的invoke方法修改, 成功.

namespace Test
{
    public partial class frmVisitControl : Form
    {
        public frmVisitControl()
        {
            InitializeComponent();
        
        }

        private void SetLabelText()
        {          
            label1.Text = "Hello";
        }

        delegate void delabc();
        public void setText()
        {
            delabc a = SetLabelText;
            label1.Invoke(a, null);
        }
      
        private void btnVisitLabel_Click(object sender, EventArgs e)
        {
            Thread th = new Thread(setText);           
            th.Start();
        }
    }
}

3.使用c#2.0提供的匿名(代理)方法,省一点代码.

namespace Test
{
    public partial class frmVisitControl : Form
    {
        public frmVisitControl()
        {
            InitializeComponent();
        
        }

        delegate void delabc();
        public void setText()
        {
            delabc a = delegate() { label1.Text = "Hello"; };

            label1.BeginInvoke(a);
        }
      
        private void btnVisitLabel_Click(object sender, EventArgs e)
        {
            //以下这句将引发InvalidOperationException
            Thread th = new Thread(setText);
          
            th.Start();
        }
    }
}

 

4.使用c#3.5, 4.0中的Action委托, 连代理声明那句都省了.

namespace Test
{   
    public partial class frmVisitControl : Form
    {
        public frmVisitControl()
        {
            InitializeComponent();
        }

        public void setText()
        {
            Action a = delegate() { label1.Text = "Hello"; };
            label1.BeginInvoke(a);
        }

        private void btnVisitLabel_Click(object sender, EventArgs e)
        {
            Thread th = new Thread(setText);
            th.Start();
        }
    }
}

注释:Action委托,用来封装一个方法,该方法不具有参数并且不返回值。 与之对应的是Func委托,它可以有返回值.

posted on 2011-09-23 14:42  BobLiu  阅读(992)  评论(0编辑  收藏  举报