我正在使用一个相当复杂的GUI,并且正在尝试将大量数据从GUI传递到backgroudWorker.我遇到的问题是从后台工作程序访问一些GUI值.例如,如果我尝试获取ComboBox.Text,则会由于交叉线程而收到InvalidOperationException.但是,如果我说做TextBox.Text,一切似乎都可以正常工作.当然,我是C#的新手,所以我不清楚其中的一些为什么还可以,而另一些却失败了.
我想出了几种方法来解决我的问题,但是我正在寻求有C#经验的人的最佳实践.
这是我可以想到的几种解决方法
>创建要传递给后台工作程序的所有值的类/结构,并在调用RunworkAsync时将其传递给该值.我觉得这没有什么吸引力,因为我必须为GUI上的每个页面构建一个类/结构以传递给backgroundWorker
>创建一堆具有特定任务的不同背景工作人员.我在传递数据时仍然遇到一些问题,但是必须传递的数据量大大减少了.但是,DoWork / ProgressChanged / RunworkerCompleted的数量明显增加,这不理想.
>(这使我了解到我目前正在做什么)
创建代表和方法以捕获信息
private delegate string ReadComboDelegate(ComboBox c);
private string ReadComboBox(ComboBox c)
{
if(c.InvokeRequired)
{
ReadComboDelegate del = new ReadComboDelegate(this.ReadComboBox);
return (string) c.Invoke(del,c);
}
else
{
return c.Text
}
}
然后在DoWork中,执行类似字符串txt = this.ReadComboBox(this.comboBox1);的操作.
当您具有简单的GUI且不必传递大量数据时,这是一个非常简单的问题.但是,项目越多,GUI越复杂,此问题就越大.如果有人有任何信息可以简化此过程,我将不胜感激.
谢谢
解决方法:
您遇到的跨线程问题是由于要求仅允许UI线程“触摸” UI控件.
我认为,将数据传递给后台工作者的最一致的方法是您的解决方案#1-创建一个简单的结构,其中包含执行处理所需的所有数据.
这比为UI中的每个控件创建ReadXXX方法要简单得多,并且它定义了后台进程执行任务所需的内容…