一个很常见的多线程问题,敬请微软专家关注!!!

5drush 2002-04-20 05:23:21
常常需要在工作线程中改变主界面线程中的控件属性来反映后台的工作情况,但是微软专家好象不推荐这么做,参见这个帖子:

感谢您使用微软产品!

在一个线程中创建的控件,不可以将父窗体设为另一个线程中的窗体和控件,这是设计使然。当然,您可以在主线程中创建控件,然后在工作线程对这些空间进行处理。请注意,有些关于UI的处理也是不能在工作线程中进行的。

-微软全球技术中心 VC技术支持

那我怎么将工作线程中完成任务的情况向UI汇报呢?
...全文
46 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
kikyang 2003-01-21
  • 打赏
  • 举报
回复
是啊,我也很想知道怎样解决的!!!
dy_2000_abc 2002-09-27
  • 打赏
  • 举报
回复
5drush(五农民出狗),后来你是怎么解决这问题的?贴出来学习 :)
javaduke 2002-05-11
  • 打赏
  • 举报
回复
运用Invoke方法。
WUYONG 2002-04-23
  • 打赏
  • 举报
回复
我搞不懂了!
不要为多线程而多线程,又不是做教学DEMO。
我的多线程原则:
1、一个线程占着CPU不干活,去等其他低速设备或者干脆怠工时;
2、我觉得经理对我不地道,想让他今后有搞不完的乐趣时。

拿UI这类的东西练多线程,很好!很好!很好!
是个优秀的反面教材!
同志们,关于去耦这一节如果没有其他问题的话,可以参考本章qqchen79(知秋一叶)2002-04-21 03:11:00 的意见。
pop133 2002-04-23
  • 打赏
  • 举报
回复
5drush(五农民出狗)说的没错!我也遇到过同样的问题!
以前用的是vb不能创建多线程,用的是com的方法来实现的!
现在c#支持多线程,又有这么多的局限性!是不是解决问题的基本思路不是很对?5drush(五农民出狗)说的是一个比较慢的网络数据读入过程还好点!我这里可是接受网络中数据的自动刷新阿!没什么好的方法?除了时时读取,winsock 别的也没什么了吧?
5drush 2002-04-23
  • 打赏
  • 举报
回复
to wuyong(WY):
我并没有为了多线程而多线程,我的程序中有一个比较慢的网络数据读入过程(瓶颈不在CPU,在于网络速度),如果将这个过程放在UI线程(主线程)中的话,每当读取数据的时候,程序就好象死机失去响应了一样。我觉得我现在面临的问题好象就是需要用到多线程才能解决,你认为我的设计有问题的话,觉得应该怎么办才能解决?
qqchen79 2002-04-22
  • 打赏
  • 举报
回复
这样只是改变DataView的DataViewRowState = CurrentRows就可以了吧?
不用手工把所有新的Row都加进去的。
countryroad 2002-04-22
  • 打赏
  • 举报
回复
是啊,exception是些什么啊?贴出来看看。
5drush 2002-04-22
  • 打赏
  • 举报
回复
to qqchen79(知秋一叶) :
这个就不好描述了,告诉我你的email?我把程序发给你帮我看看吧,是一个csdn的离线浏览器,能自动的下载网上的帖子并保存到数据库,并能根据帖子的位置自动选择读取方法,还计划能跟踪网上帖子的状态,如果有人回复能自动提醒。。。中间层的代码逻辑差不多已经构建完毕了,现在剩下界面这里比较麻烦,我想你会对此感兴趣的。
qqchen79 2002-04-22
  • 打赏
  • 举报
回复
也许不是宪成相关的问题呢?
再回头看看你的程序逻辑吧,有没有问题。
另外Exception内容是什么?出现在那些操作里面?
5drush 2002-04-22
  • 打赏
  • 举报
回复
我顶
5drush 2002-04-22
  • 打赏
  • 举报
回复
完了,以前我说的“如果我是更新dataset的话,变化不会反映到datagrid”是错误的,现在发现不管是用dataview的addnew方法一条一条的增加,还是先把数据存在临时的table里再用dataset的merge方法来合并数据表,都会造成datagrid的快速刷新而出错 :(

5drush 2002-04-21
  • 打赏
  • 举报
回复
to qqchen79(知秋一叶) :
这种方法有个问题,前面没说明白,如果我是更新dataset的话,变化不会反映到datagrid,只有更新那个赋给datagrid数据源的dataview的时候(用addnew方法)才会将数据变化反映到datagrid。这时候我希望变化反映到datagrid,但是不希望快速刷新导致出错。如果采用您说的批量更新的方法,好象dataview不支持,只有dataset才支持批量更新(但是这个时候又不能将数据变化自动的反映到datagrid),想向dataview里添加数据的话,又只能用addnew一条一条的加 :(

to countryroad(罗宾):
datagrid的刷新是在主界面线程中,是系统自动刷新的,我只是在工作线程中刷新了一个dataview,而这个dataview就是datagrid的datasource(是在主线程中创建的),所以会引起datagrid的自动刷新。这时常常导致datagrid因为快速刷新而产生非法操作。
countryroad 2002-04-21
  • 打赏
  • 举报
回复
我知道在vc中,线程之间直接传递控件对象是不行的,但可以通过传递句柄来操作。
5drush的设计好像没有问题嘛,datagrid的刷新在那个线程中?
qqchen79 2002-04-21
  • 打赏
  • 举报
回复
主线程 + 工作线程 = 多线程 :)
已经有可能出现问题了,但要是具体情况而定。

这种刷新错误应该是因为UI更新频繁造成的(可以说这是多先程引起的,因为主线程负责datagrid的绘制,而工作线程在不停的修改它的值),为什么不在循环过程中建立一个临时的存储,出了循环之后统一加入dataset呢?
至于牵扯到Control的线程安全,我觉得还是小心遵守比较好,否则光是考虑是不是会出问题就会想破头。
5drush 2002-04-21
  • 打赏
  • 举报
回复
问题是我只有一条工作线程啊,难道这样也要考虑线程安全?
还有,我将datagrid的数据源设置为一个dataset的dataview,然后在一条工作线程中有时候会有一个循环不停的往dataset里添加数据的过程,这样的设计会不会有问题?如果没有问题的话,这种方法常常导致datagrid因为快速闪烁刷新而出现错误。是datagrid本身的原因吗?

btw:菜鸟VS高手,5drush可能是胜算最大的一种打法 :)
qqchen79 2002-04-21
  • 打赏
  • 举报
回复
BTW: 五农民出狗很危险,就像在“主线程中创建控件,然后在工作线程对这些空间进行处理”一样危险。
因为如果扑不到又丧失了生产能力,就在也没机会了。:)
(If you don't know what I'm talking about, simply ignore this)
qqchen79 2002-04-21
  • 打赏
  • 举报
回复
其实这里有两个问题:

1. 在一个线程中创建的控件,不可以将父窗体设为另一个线程中的窗体和控件。
这个是情理之中的,Form的消息队列挂在Thread上, 父/子窗口不在同一个线程中显然会使情况比较混乱,即是可行也不会是好的设计。

2. 可以在主线程中创建控件,然后在工作线程对这些空间进行处理。
这是可以的,但相当危险。在Windows上Form本身存在于一个STA当中,也就是说它自身不是线程安全的,跨越线程的函数调用必须经过Marshal。麻烦啊!

我觉得就设计来说,可以采用类似Model-View的架构:
有一个存在于主线程中的View控制类管理所有UI相关的操作,建立各种线程安全(加lock)的工具函数。
工作线程本身不涉及任何直接UI的操作,需要的时候调用View控制类的相关函数完成任务,由于这些函数是线程安全的,所以在Worker Thread里就不用考虑与UI相关的县城问题了。
WUYONG 2002-04-20
  • 打赏
  • 举报
回复
我没有做过实际的东西。
从OO方法论的角度看,你应该在工作线程中调用UI线程的方法,由UI线程的方法去修改。
希望没有误导你。别砍我就行-:)
ejetcs 2002-04-20
  • 打赏
  • 举报
回复
http://www.codeguru.com/cs_syntax/WorkerThread.html这有一个例子
加载更多回复(3)

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧