跨线程操作无效:从创建它的线程以外的线程访问控制我有一个场景。(Windows Forms,C#,.NET)有一个主要表单托管一些用户控件。用户控件执行一些繁重的数据操作,这样如果我直接调用该UserControl_Load方法,则UI在加载方法执行的持续时间内变得无响应。为了克服这个问题,我在不同的线程上加载数据(尝试尽可能少地更改现有代码)我使用了后台工作线程来加载数据,完成后会通知应用程序已经完成了它的工作。现在来了一个真正的问题。所有UI(主窗体及其子用户控件)都是在主要主线程上创建的。在usercontrol的LOAD方法中,我基于userControl上的某些控件(如文本框)的值来获取数据。伪代码看起来像这样:代码1UserContrl1_LoadDataMethod(){ if (textbox1.text == "MyName") // This gives exception { //Load data corresponding to "MyName". //Populate a globale variable List<string> which will be binded to grid at some later stage. }}它给出的例外是跨线程操作无效:从创建它的线程以外的线程访问控制。为了更多地了解这一点,我做了一些谷歌搜索,并提出了一个建议,如使用下面的代码代码2UserContrl1_LoadDataMethod(){ if (InvokeRequired) // Line #1 { this.Invoke(new MethodInvoker(UserContrl1_LoadDataMethod)); return; } if (textbox1.text == "MyName") // Now it wont give an exception { //Load data correspondin to "MyName" //Populate a globale variable List<string> which will be binded to grid at some later stage }}但是但是......似乎我又回到原点了。应用程序再次无响应。这似乎是由于条件#1执行。加载任务再次由父线程完成,而不是我生成的第三个。我不知道我是否认为这是对还是错。我是线程新手。如何解决这个问题以及阻止执行第1行的影响是什么?情况是这样的:我想根据控件的值将数据加载到全局变量中。我不想从子线程更改控件的值。我不打算从子线程中做到这一点。因此只访问该值,以便可以从数据库中获取相应的数据。
5 回答
手掌心
TA贡献1942条经验 获得超3个赞
您只想使用Invoke或BeginInvoke来完成更改UI所需的最少工作量。你的“重”方法应该在另一个线程上执行(例如通过BackgroundWorker),然后使用Control.Invoke / Control.BeginInvoke来更新UI。这样你的UI线程就可以自由处理UI事件等。
请参阅我的线程文章以获取WinForms示例 - 虽然文章是在BackgroundWorker到达现场之前编写的,但我担心我没有在这方面更新它。BackgroundWorker只是略微简化了回调。
POPMUISE
TA贡献1765条经验 获得超5个赞
我遇到了这个问题,FileSystemWatcher
发现以下代码解决了这个问题:
fsw.SynchronizingObject = this
然后,控件使用当前表单对象来处理事件,因此将在同一个线程上。
守着一只汪
TA贡献1872条经验 获得超3个赞
我现在知道太晚了。但是,即使在今天,如果您在访问跨线程控件时遇到问题?这是迄今为止最短的答案:P
Invoke(new Action(() => { label1.Text = "WooHoo!!!"; }));
这是我从线程访问任何表单控件的方式。
- 5 回答
- 0 关注
- 807 浏览
添加回答
举报
0/150
提交
取消