线程和匿名方法中的代理 - 更新新线程中的控件

时间:2012-01-18 06:27:24

标签: c# multithreading c#-4.0 delegates

我在窗口中使用多线程。以下是我的课。 我在我的设计器中有一个标签控件,在新创建的线程下我正在更新它的文本属性。

以下是我在委托“Del”中封装函数“UpdateLabel”的情况。 它工作正常。

public partial class DynamicType : Form
    {
        delegate void Del(String x);

        public DynamicType()
        {
            InitializeComponent();
        }

        private void DynamicType_Load(object sender, EventArgs e)
        {
            System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(StartThread));
            t.Start();
        }

        private void StartThread()
        {
            this.Invoke(new Del(UpdateLabel), new object[] { "Hi" });
        }

        private void UpdateLabel(String str)
        {
            label1.Text = str;
        }
    }

我有一个名为匿名方法的案例。实现匿名方法后 在以下方法中。以下是定义。

private void StartThread()
        {
            UpdateLabel("Hi");
        }



private void UpdateLabel(String str)
        {
            Del Label = delegate(String k)
             {
                 label1.Text = k;

             };
            Label("hi");
        }

跨线程操作无效:控制'label1'从其创建的线程以外的线程访问。

我的查询是在前一种情况下,我使用委托,它工作正常,在匿名方法的情况下,我通过直接实例化委托删除额外的功能,并尝试更新标签控制文本属性,它给崩溃上文提到的。原因是什么?

1 个答案:

答案 0 :(得分:1)

在第一个示例中,您在UI线程中调用标签更新(通过Form.Invoke)。这是正确的,有效:

this.Invoke(new Del(UpdateLabel), new object[] { "Hi" });

在第二个示例中,您将在后台线程中创建一个委托,并在后台线程中启动该委托。这不起作用,因为后台线程不允许更新UI:

Del Label = delegate(String k) { label1.Text = k; }; 
Label("hi");   // runs in the same thread

要解决此问题,您必须使用this.Invoke在UI线程中执行委托:

Del Label = delegate(String k) { label1.Text = k; }; 
this.Invoke(Label, new object[] {"hi"});   // runs in the UI thread