为什么在此代码中使用Action?

时间:2011-05-10 13:16:21

标签: c# multithreading action invoke

您好 我看到以下代码:

void UpdateMessage (string message)
{
    Action action = () => txtMessage.Text = message;
    this.Invoke (action);
}

为什么使用Action然后在此处调用操作?为什么不使用txtMessage.Text = message替换函数体中的代码?


更新

在评论中提供的更完整版本的代码,下面再现了语法高亮,缩进等。

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
        InitializeComponent(); 
        new Thread(Work).Start(); 
    } 

    void Work() 
    { 
        Thread.Sleep(5000); 
        UpdateMessage("My Garden"); 
    } 

    void UpdateMessage(string message) { 
        Action action = () => textBox1.Text = message; 
        this.Invoke(action); 
    } 
} 

3 个答案:

答案 0 :(得分:20)

因为此代码在与UI不同的线程上运行,并且必须使用Invoke编组到UI线程。

Control.Invoke()州的documentation

  

在拥有控件底层窗口句柄的线程上执行指定的委托。

这是必要的,因为底层Windows框架要求窗口句柄上的操作由拥有窗口句柄的线程执行。

答案 1 :(得分:12)

如果从另一个线程调用UpdateMessage,则需要调用主线程才能与GUI元素交互

如果仅使用txtMessage.Text = message,则会获得CrossThreadOperationException

答案 2 :(得分:4)

您应该在UI线程中使用控件的属性,否则您将收到异常。

Control.Invoke()将通过向窗口消息循环发送Windows消息来执行您的委托。

但是,您可以优化代码以防止在不需要时进行不必要的线程同步:

void UpdateMessage (string message)
{
    if(InvokeRequired)
    {
        Invoke((Action)()=>UpdateMessage(message));
        return;
    }

    txtMessage.Text = message;
}