WinForms线程安全控制访问

时间:2011-05-23 03:22:46

标签: winforms thread-safety

当我尝试访问WinForms控件时,我收到错误Control accessed from a thread other than the thread it was created on。我知道控制的所有修改都应该在UI线程中执行(需要BeginInvoke()等),但我需要我的控件只能读取。

这是我的简化代码:

string text = textBox.Text;

从另一个线程访问WinForms控件的属性值的模式是什么?

2 个答案:

答案 0 :(得分: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;
            }
        }
    }
}

然后在另一个线程中你可以像这样调用文本框:

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();

答案 1 :(得分:0)

必须使用BeginInvoke。如果需要返回值(例如,控件的Text内容),可以使用EndInvoke等待完成。

那就是说,你可能想要考虑做其他事情;让GUI线程“推送”数据到后台工作线程。这有助于减少与用户输入竞争的机会,并且可以实现更清晰的设计,并清晰地分离GUI和核心逻辑。

相关问题