在课堂上,我有一个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;
}
答案 0 :(得分:1)
通常来说,不需要从工作线程访问UI元素。
您应该更改方法。我想您使用的是.NET Framework 4.5或更高版本,因此有一个适合您的模式:TAP,通常称为async
/ await
。
使用这种模式,您无需关心线程。框架会为您关心它们。您的任务是告诉编译器,异步操作需要执行什么操作。
仅举一个例子-将Button
的{{1}}事件的事件处理程序更改为以下内容:
Click