WinForms线程安全控制访问
当我尝试访问WinForms控件时,我从创建错误控件的线程以外的线程访问错误控件。我知道所有控件的修改都应该在需要BeginInvoke等的UI线程中执行,但我需要我的控件是只读的 以下是我的简化代码:WinForms线程安全控制访问,winforms,thread-safety,Winforms,Thread Safety,当我尝试访问WinForms控件时,我从创建错误控件的线程以外的线程访问错误控件。我知道所有控件的修改都应该在需要BeginInvoke等的UI线程中执行,但我需要我的控件是只读的 以下是我的简化代码: string text = textBox.Text; 从另一个线程访问WinForms控件属性值的模式是什么?必须使用BeginInvoke。如果需要返回值,例如控件的文本内容,可以使用EndInvoke等待完成 说,你可能想以另一种方式考虑事情。让GUI线程将数据“推送”到后台工作线程。这
string text = textBox.Text;
从另一个线程访问WinForms控件属性值的模式是什么?必须使用BeginInvoke。如果需要返回值,例如控件的文本内容,可以使用EndInvoke等待完成
说,你可能想以另一种方式考虑事情。让GUI线程将数据“推送”到后台工作线程。这有助于减少与用户输入竞争的机会,并使设计更清晰,GUI和核心逻辑清晰分离。对于这样的小事,您不必特别使用BeginInvoke,您也可以使用Invoke,但确实需要在UI线程上调用。您可以使用一些魔法在几个方法调用中隐藏讨厌的细节,然后使用扩展方法使其更干净。例如,假设我想用两个ADSAFE方法来扩展TextBox控件,以获取和设置Text属性。我可能会这样做:
namespace System.Windows.Forms
{
public static class TextBoxExtensions
{
public static string GetTextThreadSafe(this TextBox box)
{
return GetTextBoxText(box);
}
public static void SetTextThreadSafe(this TextBox box, string str)
{
SetTextBoxText(box, str);
}
public static string GetTextBoxText(TextBox box)
{
if (box.InvokeRequired)
{
Func<TextBox, string> deleg = new Func<TextBox, string>(GetTextBoxText);
return box.Invoke(deleg, new object[] { box }).ToString();
}
else
{
return box.Text;
}
}
public static void SetTextBoxText(TextBox box, string str)
{
if (box.InvokeRequired)
{
Action<TextBox, string> deleg = new Action<TextBox, string>(SetTextBoxText);
box.Invoke(deleg, new object[] { box, str });
}
else
{
box.Text = str;
}
}
}
}
Thread t = new Thread(new ThreadStart(() =>
{
// Threadsafe call to set the text
SomeTextBox.SetTextThreadSafe("asdf");
// Threadsafe call to get the text
MessageBox.Show(SomeTextBox.GetTextThreadSafe());
}));
t.IsBackground = true;
t.Start();