从另一个线程从TextBox获取文本

时间:2018-11-29 10:50:37

标签: c# winforms thread-safety ui-thread

在课堂上,我有一个TextBox:

public class TextBoxAdapter {

    private System.Windows.Forms.TextBox textBox;

    //...some code that initializes the textBox...

    public string getTextFromBox() {
        if( textBox.InvokeRequired )
            return (string)textBox.Invoke( (Func<string>)delegate { return textBox.Text; } );
        else
            return textBox.Text;
    }
}

要从另一个线程安全地访问此TextBox,我想使用Invoke机制。但是函数getTextFromBox()在使用Invoke()的那一行失败。我通过在此行放置一个断点并按F10(跳过)来验证了这一点。它毫无例外地失败了。我的调用方式有误吗?

修改

为什么我需要从另一个线程访问文本框?我试图在每次单击按钮时创建一个新线程,以防止UI冻结。例如。在用户登录窗口上,当按下登录按钮时,将启动一个新线程来通知和观察者。然后,观察者想要读取用户名和密码文本框的值,以检查登录名是否有效。

一个奇怪的事情是:写入文本框可以正常工作。我使用的代码:

        if ( textBox.InvokeRequired ) {
            MethodInvoker setText = new MethodInvoker( () => {
                textBox.Text = text;
            } );
            textBox.BeginInvoke( setText );
        }
        else {
            textBox.Text = text;
        }

1 个答案:

答案 0 :(得分:1)

通常来说,不需要从工作线程访问UI元素。

您应该更改方法。我想您使用的是.NET Framework 4.5或更高版本,因此有一个适合您的模式:TAP,通常称为async / await

使用这种模式,您无需关心线程。框架会为您关心它们。您的任务是告诉编译器,异步操作需要执行什么操作。

仅举一个例子-将Button的{​​{1}}事件的事件处理程序更改为以下内容:

Click