线程方法问题

soo*_*ise 4 c# lambda

我正在使用以下方法来显示无模式消息框.

public void ShowMessageBox(string Message)
{
  var thread = new Thread(
    () =>
    {
      MessageBox.Show(Message);
    });
  thread.Start();
}
Run Code Online (Sandbox Code Playgroud)

"()=> {...}"是我以前从未见过的.这个代码模式的名称是什么?

此外,thread.Start启动线程,一旦"()=> {...}"方法完成(当消息框正常时)它会自动关闭,对吧?如果是这样,你能指点一些官方文件说线程自动关闭吗?

谢谢!

STW*_*STW 7

它是lambda运算符,读作"转到".MSDN有一个很好的介绍:Lambda表达式(C#编程指南)

你的榜样的一个问题是,你旋转了一个新的线程来更新UI,用户界面本质上是单线程的,所以后台更新一般是错误的事情(除非你手动/显式检查InvokeRequired,并呼吁Invoke()为需要.


关于UI线程......

在WinForms中,每个FormControl在特定线程("UI线程")上创建,您可以将该线程视为拥有该控件(不完全正确,但是将其概念化的好方法).从该线程更新UI是安全的,从另一个线程更新UI会带来冲突和损坏的风险以及并行/异步编程的所有常见风险.

...那么......如何在不阻止UI的情况下安全地从后台线程更新UI?简而言之 - 你不能 - 你可以做的最好的事情是阻止它更新UI所需的最低限度.这是InvokeRequiredInvoke()在来...

这是一个示例:您应该能够使用按钮和文本框将其放入新表单的代码隐藏中.

使用:

  • 尝试注释掉要么调用SetTextAsyncSafe()SetTextAsyncSafe()- (?他们正在运行的异步,记不清了)同时运行可能会迷惑你,因为他们不一定会在他们调用的顺序执行.

  • 然后设置断点SetText().您应该看到"安全"的通话将实际调用该方法两次-第一次调用将检测InvokeRequired并调用方法正确的线程第二次通过Invoke()"ING它.

  • SetTextAsyncUnsafe()实际获取textBox1.Text = value;语句时,您应该看到抛出异常.例外情况将是InvalidOperationException一条消息,指出"跨线程操作无效" - 您可以谷歌这个术语获取更多详细信息.

代码:

private void button1_Click(object sender, EventArgs e)
{
  SetTextAsyncSafe("This update was made from the UI Thread by using Invoke()");
  SetTextAsyncUnsafe("This update was made directly from the background thread and can cause problems");
}

private void SetTextAsyncUnsafe(string value)
{
  new Thread(() => SetText(value, false)).Start();
}

private void SetTextAsyncSafe(string value)
{
  new Thread(() => SetText(value, true)).Start();
}

private void SetText(string value, bool checkInvokeRequired)
{
  if (checkInvokeRequired) 
  {
    if (InvokeRequired) 
    {
      Invoke(new Action(() => SetText(value, checkInvokeRequired)));
      return; // early exit
    }
  }

  textBox1.Text = value;
}
Run Code Online (Sandbox Code Playgroud)