如何访问 UI 线程上的值?

Cor*_*rey 3 c# multithreading

我在调用 UI 控件上的操作时没有任何问题BeginInvoke,但是,这是一种void方法。我需要从文本框中获取一个值以在不同的线程中使用。

我怎样才能做到这一点?

Dan*_*ner 5

最简单的解决方案是在闭包中捕获局部变量。

String text;
textBox.Invoke(() => text = textBox.Text);
Run Code Online (Sandbox Code Playgroud)

编译器会生成一些代码,这很像 chibacity 的解决方案——局部变量成为编译器生成的类的一个字段。

更新

这不起作用 - lambda 表达式不可分配给Delegate. 这个问题可以使用扩展方法来解决。

internal void ExecuteOnOwningThread(this Control control, Action action)
{
    if (control.InvokeRequired)
    {
        control.Invoke(action);
    }
    else
    {
        action();
    }
}
Run Code Online (Sandbox Code Playgroud)

用法如下。

String text;
textBox.ExecuteOnOwningThread(() => text = textBox.Text);
Run Code Online (Sandbox Code Playgroud)

可以将多个语句填充到 lambda 表达式中。

textBox.ExecuteOnOwningThread(() =>
{
    DoStuff();
    text = textBox.Text
    DoOtherStuff();
});
Run Code Online (Sandbox Code Playgroud)

但是正如在评论中已经提到的 chibacity,明确地编写一个方法可能会更好。超过某一点使用 lambda 表达式将对代码的可读性产生不利影响。并且使用 lambda 表达式当然很容易引入重复的代码。