从另一个线程的 TextBox 中获取文本
Get text from TextBox from another thread
在 class 我有一个 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 冻结。例如。在用户登录 window 时,当按下登录按钮时,将启动一个新线程来通知和观察者。然后观察者想要读取用户名和密码文本框的值以检查登录是否有效。
奇怪的是:写入文本框没有任何问题。我使用的代码:
if ( textBox.InvokeRequired ) {
MethodInvoker setText = new MethodInvoker( () => {
textBox.Text = text;
} );
textBox.BeginInvoke( setText );
}
else {
textBox.Text = text;
}
一般来说,应该没有必要从工作线程访问 UI 元素。
你应该改变你的方法。我想您使用的是 .NET Framework 4.5 或更新版本,因此有一个适合您的模式:TAP,通常称为 async
/await
.
使用此模式,您无需关心线程。框架会为您关心它们。您的任务是告诉编译器,什么需要作为异步操作执行。
举个例子 - 将 Button
的 Click
事件的事件处理程序更改为如下内容:
async void LoginButton_Click(object sender, EventArgs e)
{
// This runs on the UI thread
string login = loginTextBox.Text;
string password = pwdTextBox.Text;
loginButton.Enabled = false;
// This will be executed asynchronously, in your case - on a worker thread
bool success = await Task.Run(() => myLoginProcessor.Login(login, password));
// This runs again on the UI thread, so you can safely access your controls
if (success)
{
labelResult.Text = "Successfully logged in.";
}
else
{
labelResult.Text = "Invalid credentials.";
}
loginButton.Enabled = true;
}
在 class 我有一个 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 冻结。例如。在用户登录 window 时,当按下登录按钮时,将启动一个新线程来通知和观察者。然后观察者想要读取用户名和密码文本框的值以检查登录是否有效。
奇怪的是:写入文本框没有任何问题。我使用的代码:
if ( textBox.InvokeRequired ) {
MethodInvoker setText = new MethodInvoker( () => {
textBox.Text = text;
} );
textBox.BeginInvoke( setText );
}
else {
textBox.Text = text;
}
一般来说,应该没有必要从工作线程访问 UI 元素。
你应该改变你的方法。我想您使用的是 .NET Framework 4.5 或更新版本,因此有一个适合您的模式:TAP,通常称为 async
/await
.
使用此模式,您无需关心线程。框架会为您关心它们。您的任务是告诉编译器,什么需要作为异步操作执行。
举个例子 - 将 Button
的 Click
事件的事件处理程序更改为如下内容:
async void LoginButton_Click(object sender, EventArgs e)
{
// This runs on the UI thread
string login = loginTextBox.Text;
string password = pwdTextBox.Text;
loginButton.Enabled = false;
// This will be executed asynchronously, in your case - on a worker thread
bool success = await Task.Run(() => myLoginProcessor.Login(login, password));
// This runs again on the UI thread, so you can safely access your controls
if (success)
{
labelResult.Text = "Successfully logged in.";
}
else
{
labelResult.Text = "Invalid credentials.";
}
loginButton.Enabled = true;
}