"跨线程操作无效"异常时,试图让组合框的值 [英] "Cross-thread operation is not valid" exception when trying to get value of comboBox

查看:132
本文介绍了"跨线程操作无效"异常时,试图让组合框的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

"Cross-thread operation is not valid" exception

我经历了这个例外很多次,但所有这些时候,我设置一个控件的值。那个时候我解决了使用 SetControlPropertyThreadSafe(),称为函数只建议是由某人stackoverflow.com。但是,这一次我得到当我试图让组合框的值,这个异常。这里是code:

I experienced this exception many times, but all those times I was setting the value of a control. That time I solved using a function called SetControlPropertyThreadSafe(), which was suggested by someone on stackoverflow.com only. But this time I am getting this exception when I am trying to get the value of comboBox. Here is the code:

 string cat;
        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text.Trim().Length > 20)
            {
                System.Threading.Thread t = new System.Threading.Thread(addQuickTopic);
                t.Start();
            }
            else
                MessageBox.Show("The length of the title must be greater than 20", "Title length invalid", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }
        public string tTitle="";
        void addQuickTopic()
        {
            Global.SetControlPropertyThreadSafe(button1, "Text", "Working...");
            Global.SetControlPropertyThreadSafe(button1, "Enabled", false);
            Topic t = new Topic();
            t.setTitle(textBox1.Text);
            t.setDescription(" ");
            t.setDesID(Global.getMd5Hash(Common.uid+DateTime.Today.ToString()+DateTime.Today.Millisecond.ToString()));
            t.setUsrID(Common.uid);
            t.setReplyToID("");
            t.setConDate("0");
            cat = CategoryList.SelectedValue.ToString();

正如你可以看到,我直接得到textBox1.Text不作任何线程安全运行。但在试图获取组合框的选定值时的最后一行,我得到这个例外。因此,任何一个可以请建议我做什么,在这种情况呢?以下是code我的线程安全功能设置控件的值:

As you can see I am getting the textBox1.Text directly without applying any thread safe operation. But at the last line when trying to fetch comboBox's selected value, I am getting this exception. So can any one please suggest me what to do in this situation? Following is the code for my thread safe function for setting control's value:

public static void SetControlPropertyThreadSafe(Control control, string propertyName, object propertyValue)
        {
            try
            {
                if (control.InvokeRequired)
                {
                    control.Invoke(new SetControlPropertyThreadSafeDelegate(SetControlPropertyThreadSafe), new object[] { control, propertyName, propertyValue });
                }
                else
                {
                    control.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, control, new object[] { propertyValue });
                }
            }
            catch (Exception)
            { }
        }

如果我需要建立一个类似 GET 功能?还是有其他的解决方案可用?

Should I need to create a similar get function? Or any other solution available?

推荐答案

现在,你得到的文本框,通过值: t.setTitle(textBox1.Text); 。这也将失败。

Right now, you're getting the value from the TextBox, via: t.setTitle(textBox1.Text);. This will also fail.

如果我需要建立一个类似的get函数?还是有其他的解决方案可用?

Should I need to create a similar get function? Or any other solution available?

是的,你需要获取一个选项。我建议不使用反射和文字,但是,这种返工使用泛型方法和lambda表达式。

Yes, you need an option for get. I would recommend not using reflection and text, however, and rework this to use generic methods and lambdas.

public static void SetControlPropertyThreadSafe<T>(T control, Action<T> action) where T : Control
    {
            if (control.InvokeRequired)
            {
                control.Invoke(action);
            }
            else
            {
                action();
            }
    }

这将使你写这个强类型,即:

This would allow you to write this strongly typed, ie:

Global.SetControlPropertyThreadSafe(button1, b => b.Text = "Working...");

您也可以使一个强类型get方法:

You can also make a strongly typed get method:

public static U GetControlPropertyThreadSafe<T,U>(T control, Func<T,U> func) where T : Control
{
     if (control.InvokeRequired)
     {
         return (U)control.Invoke(func, new object[] {control});
     }
     else
     {
         return func(control);
     }
}

然后让你写的:

Which then lets you write:

 t.setTitle(Global.GetControlPropertyThreadSafe(textBox1, t => t.Text));

您也可以使用同样的方法来获取和设置的组合框项目。

You could also use the same methods for getting and setting the combo box items.

这篇关于&QUOT;跨线程操作无效&QUOT;异常时,试图让组合框的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆