lev*_*ovd 2 thread-safety winforms
Control accessed from a thread other than the thread it was created on当我尝试访问WinForms控件时出错.我知道控制的所有修改都应该在UI线程中执行(需要BeginInvoke()等),但我需要我的控件只能读取.
这是我的简化代码:
string text = textBox.Text;
Run Code Online (Sandbox Code Playgroud)
从另一个线程访问WinForms控件的属性值的模式是什么?
小智 5
对于像这样简单的东西,你不必专门使用BeginInvoke,你也可以使用Invoke,但是你确实需要在UI线程上调用调用.您可以使用一些魔法来隐藏几个方法调用中令人讨厌的细节,然后使用扩展方法使其更清晰.例如,假设我想用一些用于获取和设置Text属性的安全方法来扩展TextBox控件.我可能会这样做:
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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在另一个线程中你可以像这样调用文本框:
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();
Run Code Online (Sandbox Code Playgroud)