程序描述如下:
主线程会持续发出一系列EventClock事件,所有的10000个CWacher对象都会对每一个EventClock事件做出相应。
在单线程情况下,所有10000个CWatcher的对象是按照addhandler..addressof..语句定义的顺序依次执行响应程序的。
问题是这样:我希望当第一个EventClock事件发出后,所有CWatcher通过线程池操作并发响应这个事件,而主线程等待所有对象响应完成之后再发出第二个EventClock事件。请问如何能够实现呢?这个问题已经难倒过很多同行高手了~
vb.net如何用线程池实现多线程事件
发布时间:2020-12-16 22:42:51 所属栏目:大数据 来源:网络整理
导读:程序描述如下: 主线程会持续发出一系列EventClock事件,所有的10000个CWacher对象都会对每一个EventClock事件做出相应。 在单线程情况下,所有10000个CWatcher的对象是按照addhandler..addressof..语句定义的顺序依次执行响应程序的。 问题是这样:我希望当
用户名:boblaw 得分:100 时间:2007-11-27 11:35:06
用户名:wolfxin2010 得分:0 时间:2011-07-16 16:08:52
up up up,有所收获!
用户名:msdn165168 得分:0 时间:2011-04-03 19:03:40
绝对是高手,学习一下
用户名:wuyazhe 得分:0 时间:2010-12-23 10:36:36
又挖坟贴。。。
版主结贴之
用户名:pp420 得分:0 时间:2010-12-23 10:19:15
高手。。
用户名:sp1234 得分:0 时间:2010-05-20 09:10:00
“所有的10000个CWacher对象”?
感觉上,还是lz留着这个程序自己玩吧。没有设计,就不要深入了。
用户名:my_skysea 得分:0 时间:2010-05-20 09:03:28
顶,收藏了!NB!
用户名:decacrf 得分:0 时间:2010-04-26 15:51:33
mark一下
用户名:kuhura 得分:0 时间:2010-04-22 23:03:27
mark一下
用户名:nandi_1 得分:0 时间:2010-04-22 19:32:13
标记
学习
用户名:my13513480001 得分:0 时间:2010-04-22 11:15:07
【多线程】——占位学习!!!!
用户名:lsh2216024 得分:0 时间:2010-03-12 11:26:13
学习一下了。。。。。。
用户名:Going1981 得分:0 时间:2010-03-11 23:22:47
收藏了,看得一头雾水的,改天来认真学习!
用户名:wsgwywzh 得分:0 时间:2010-03-04 09:35:34
还不太明白,要加强学习.
用户名:sfp_801 得分:0 时间:2010-03-03 11:36:13
有点深,不太明白,来拿分的
用户名:rainbowsoftware 得分:0 时间:2008-07-01 14:48:50
mark
用户名:limx001 得分:0 时间:2008-04-05 12:31:27
终于遇到高人了!!! 太佩服了,虽然看不懂,但还是要顶一下,实在太厉害了!
用户名:_NET2004 得分:0 时间:2008-04-05 11:44:28
绝对是高手,学习一下
用户名:xiao1zhao 得分:0 时间:2008-04-05 10:49:40
遇到高人了,佩服下~~
用户名:kockoc4 得分:0 时间:2008-03-31 17:51:42
編程王10TB代碼庫
http://code.kingofcoders.com 10TB代碼Search engine http://search.kingofcoders.com編程王10TB代碼庫 http://code.kingofcoders.com 10TB代碼Search engine http://search.kingofcoders.com編程王10TB代碼庫 http://code.kingofcoders.com 10TB代碼Search engine http://search.kingofcoders.com編程王10TB代碼庫 http://code.kingofcoders.com 10TB代碼Search engine http://search.kingofcoders.com編程王10TB代碼庫 http://code.kingofcoders.com 10TB代碼Search engine http://search.kingofcoders.com編程王10TB代碼庫 http://code.kingofcoders.com 10TB代碼Search engine http://search.kingofcoders.com編程王10TB代碼庫 http://code.kingofcoders.com 10TB代碼Search engine http://search.kingofcoders.com編程王10TB代碼庫 http://code.kingofcoders.com 10TB代碼Search engine http://search.kingofcoders.com編程王10TB代碼庫 http://code.kingofcoders.com 10TB代碼Search engine http://search.kingofcoders.com編程王10TB代碼庫 http://code.kingofcoders.com 10TB代碼Search engine http://search.kingofcoders.com編程王10TB代碼庫 http://code.kingofcoders.com 10TB代碼Search engine http://search.kingofcoders.com編程王10TB代碼庫 http://code.kingofcoders.com 10TB代碼Search engine http://search.kingofcoders.com編程王10TB代碼庫 http://code.kingofcoders.com 10TB代碼Search engine http://search.kingofcoders.com
用户名:dombo 得分:0 时间:2007-12-07 12:44:11
现在正在做和楼主说的功能类似的程序,此贴帮助极大,断断续续看了几天,终于明白了
用户名:xsf322 得分:0 时间:2007-12-05 17:31:07
看到这样大师级人物的帖及回帖,真是惭愧,连上CSDN的勇气都没有了。。
用户名:hixiaosheng 得分:0 时间:2007-12-04 14:59:14
碰到NB人物了,不顶没有天理了。
用户名:jenny_yu 得分:0 时间:2007-12-04 11:19:02
up
用户名:woshishei 得分:0 时间:2007-12-04 11:16:17
为什么给帖子加分的时候,提示错误信息“无权使用此功能”?
用户名:kongweibin 得分:0 时间:2007-12-02 16:24:13
顶一个!!
用户名:jin3long 得分:0 时间:2007-12-02 14:38:08
哪位大哥给一段vb.net连接mdb数据库及执行相关查询的代码,是用windows窗体显示,本人菜鸟,多谢!
用户名:jinghao666666 得分:0 时间:2007-12-01 07:26:04
看贴,帮顶。
用户名:woshishei 得分:0 时间:2007-11-29 17:24:50
Bingo!
再次对boblaw和vwxyzh两大高手的联手拔刀表示万分感激!
用户名:boblaw 得分:0 时间:2007-11-29 17:12:33
但是,我原来的事件响应程序OnEventTimeClock()不知道应该怎么改动一下。
---------------------------------
还有一点,其实阻塞主线程并没有关系的 ------------------------------ 如果你的主线程确认除了触发事件,不会有其他任务,那么使用vwxyzh的方法,其核心在于使用了异步触发事件,一个BeginInvoke对应一个EndInvoke,如vwxyzh 所述,EndInvoke可以理解成Thread.Join(),如果BeginInvoke调用的过程没有完成,EndInvoke将会阻塞线程,这样可以保证所有的事件响应完成后,调用线程才会继续,这时你可以再触发下一次事件
用户名:vwxyzh 得分:0 时间:2007-11-29 16:36:51
简单的说,我的方法就是利用Custom Event,修改事件的AddHandler、RemoveHandler和RaiseEvent这3个方法。
主要是在RaiseEvent这个方法里面把原来委托默认的按顺序执行变成每一个委托执行BeginInvoke,也就是第一个循环 (BeginInvoke就是往线程池里面添加一个WorkItem,有点像Thread.Start(),不过是加到线程池里面) 后面一个循环要求每个委托都结束异步调用。 (EndInvoke可以理解成Thread.Join(),只不过是对应BeginInvoke的) 最终实现事件处理方法的并行执行。
用户名:woshishei 得分:0 时间:2007-11-29 16:04:03
说白了,多线程事件响应有四个问题现在需要解决:
一、事件响应的过程很长,一个事件处理程序不能阻止后续的事件处理程序,所以要用异步响应方式。 二、主线程需要等待所有CWatcher对象响应完毕才能发出下一个事件,但不能用循环的方式消耗资源。 三、CWatcher对象的数量远大于64个,明显WaitHandle对信号量有限制,需要突破。 四、代码的重用性和可管理性要强,因为需要扩展的类似功能很多。
用户名:woshishei 得分:0 时间:2007-11-29 15:41:24
vwxyzh和boblaw两位的补充对我再次面临的问题很有启发。
因为天资愚笨的关系,vwxyzh的方法不太懂,但好像是在尝试自定义事件异步执行(Which I tried to get better understand but failed),要是有实现的代码就好了,本来就整不太明白。boblaw的方法按照我的理解,需要靠cnt.Wait()来反复触发数量为objcnt的事件,这种方法确实突破了WaitHandle对信号量最多不能超过64的限制。但是,我原来的事件响应程序OnEventTimeClock()不知道应该怎么改动一下。 同时,回到问题的出发点,我认为自己的设计思路可能就不太正确,如果设计多线程事件响应都需要: RaiseEvent(主线程,在发出事件后同步)->OnEvent(主线程,启用线程池)->OnEventThread(分线程,处理事件) 这种模式的话,感觉这样做程序跳转就已经太多了,阅读性和代码管理性也不强,两位认为呢? 还有一点,其实阻塞主线程并没有关系的,在面向对象的设计中,主线程通常是作为控制线程,主要负责控制仿真周期、剧情事件的触发流程等等,一个仿真周期(或者剧情事件)处理完成之前,其他周期或事件必须处于等待状态,否则就会出异常。其实我在想,能不能修改响应机制,变成: RaiseEvent(主线程,在发出事件异步执行响应程序)->OnEventThread(在各自的线程中处理事件)
用户名:boblaw 得分:0 时间:2007-11-29 12:50:13
更正一下
MyCounter的FireEvent()方法应声明为Private
用户名:boblaw 得分:0 时间:2007-11-29 12:43:13
楼上的方法是可行的,但是与WaitHandle一样,会导致主线程在等待全部事件响应完成之前一直阻塞.
想了一下,设计了一个MyCounter类来实现,每调用一次Wait,MyCounter类会在所有事件完成后以事件形式通知主线程.主线程收到事件通知后,可以触发下一次事件.不会阻塞主线程,LZ可写代码中止事件的触发.已测试通过 (注:由于时间关系,这个类并不会很完善,但足以应付LZ所述的场景)
用户名:vwxyzh 得分:0 时间:2007-11-29 09:54:54
用户名:boblaw 得分:0 时间:2007-11-29 09:32:46
刚查了MSDN,的确有这个问题,WaitHandles数组成员不能超过64个.
用户名:woshishei 得分:0 时间:2007-11-28 22:20:51
一直到今天中午,运行结果一切正常。
下午突然又发现了一个新问题,就是当创建的CWatcher对象数量超过64的时候,提示错误信息“WaitHandles 的数目必须少于或等于 64 个。”指向这一句:Threading.WaitHandle.WaitAll(WaitHandleArray) 程序是用作仿真的,因此对象个数是以千为单位的数量级,如果最多只能建立64个的话,那就太少了点。请问这个问题又该怎么解决呢?
用户名:woshishei 得分:0 时间:2007-11-28 11:57:53
非常感谢boblaw黑马王子(经典,由我制造),感谢你的帮助让我打消了了同时使用多线程与面向对象设计方法的疑虑。
用户名:boblaw 得分:0 时间:2007-11-28 11:42:48
創建一個Module,寫一個Sub Main過程,如下(衹寫了重要的代碼)
設置項目屬性,在“應用程序”選項卡中,取消啟用應用程序框架,選擇啟動對象為Sub Main().
用户名:woshishei 得分:0 时间:2007-11-28 11:16:00
我做的是窗口程序,执行代码从
Private Sub StartProc_Load(ByVal sender As Object,ByVal e As System.EventArgs) Handles Me.Load 开始的,<MTAThread()>应该放在哪里呢?
用户名:boblaw 得分:0 时间:2007-11-28 10:50:04
<MTAThread()> _
Sub Main() End Sub
用户名:woshishei 得分:0 时间:2007-11-28 10:41:49
修改运行之后提示指向这句的错误信息:
Threading.WaitHandle.WaitAll(wharray) 不支持一个 STA 线程上针对多个句柄的 WaitAll。 这个信息我昨天尝试的时候也出现过,可是还没找到解决办法。
用户名:boblaw 得分:0 时间:2007-11-27 21:23:43
用户名:boblaw 得分:0 时间:2007-11-27 21:20:57
WaitHandle.WaitAll()也是.net中一种同步技术,其实很适合这种情况,使用之后,在上面的所有担心都不存在了.
但是会使用你的主线程失去响应.因为主线程必须在所有的AutoResetEvent设置为True后才继续执行. 使用方法如下:
用户名:woshishei 得分:0 时间:2007-11-27 18:18:57
谢谢boblaw,其实我一直在尝试ManualResetEvent事件这种方式,需要调用WaitHandle.WaitAll()方法
据说这样调用的话就不用通过主动循环等待事件响应,可以节省主线程资源。这种方式你会吗?
用户名:boblaw 得分:0 时间:2007-11-27 17:46:17
另外,我考虑有可能会在中途出现Counter=RCounter的情况,这样主线程就会意外跳过去。你觉得呢?
----------------------- 我認為是不可能的。主線程優先執行,相對而言線程池的效率不高,主線程很快就觸發完了事件,而線程池可能才剛開始工作。
用户名:boblaw 得分:0 时间:2007-11-27 17:36:31
1.
SyncLock syncobj1 RCounter += 1 End SyncLock 這是同步,當一個線程在訪問syncobj1時,其他線程不可以訪問syncobj1,以防止出現計數器計數錯誤的情況 2. 这个应该是While语句吧 ------------------- 使不使用while是你決定,因為你沒有告訴我是如何觸發事件的,所以我沒有使用循環. 3. 这个应该是While语句吧,这样做了消息循环之后,主线程的资源就被占用了, ----------------------- 看你如何觸發事件嘍,如何你不停主動循環去檢查是否可以觸發事件,那就資源消耗很大了。 給你個建議,每次完成處理之後,先檢查Counter是否=RCounter,如果等於就發送一個windows消息(調用win32 API sendmessage)給主窗體,由主窗體來觸發下一個事件。 這樣對主窗體來說,是被動地去觸發事件,性能會好很多。
用户名:woshishei 得分:0 时间:2007-11-27 17:29:32
另外,我考虑有可能会在中途出现Counter=RCounter的情况,这样主线程就会意外跳过去。你觉得呢?
用户名:woshishei 得分:0 时间:2007-11-27 17:21:31
好像是可以了,我还在验证结果。syncobj 和 counter 我都设成了静态变量。
SyncLock syncobj1 RCounter += 1 End SyncLock 这一段我不明白什么意思,能不能介绍一下呢。 If Counter=RCounter Then Counter=0; RCounter=0; '觸發新事件 Else '不觸發 End If 这个应该是While语句吧,这样做了消息循环之后,主线程的资源就被占用了,不便于以后响应窗口。我听说有manuresetevent可以用,不知道怎么实现。
用户名:boblaw 得分:0 时间:2007-11-27 16:31:13
按上面的處理方法,應該可以實現你的要求
用户名:boblaw 得分:0 时间:2007-11-27 16:28:30
用户名:woshishei 得分:0 时间:2007-11-27 16:05:06
嗯,你说对了,我必须要使用线程池进行并发响应,所以我就遇到了这个问题
Public Sub OnEventTimeClock(ByVal sender As Object,ByVal e As EventArgs) Dim GoOnEventTimeClock As New Threading.WaitCallback(AddressOf OnEventTimeClockThread) Threading.ThreadPool.QueueUserWorkItem(GoOnEventTimeClock,sender) Console.WriteLine("Involk" & vbTab & Me.num.ToString _ & vbTab & "IsThreadPool" & vbTab & Threading.Thread.CurrentThread.IsThreadPoolThread.ToString _ & vbTab & "ThreadID" & vbTab & Threading.Thread.CurrentThread.ManagedThreadId _ & vbTab & sender.ThisTime.ToString) End Sub Public Sub OnEventTimeClockThread(ByVal sender As Object) Threading.Thread.Sleep(2000) End Sub
用户名:boblaw 得分:0 时间:2007-11-27 15:51:43
事件的觸發,與是否處在多線程環境關無關係,事件觸發的代碼會在觸發事件的那個線程中執行
RaiseEvent一定會等待所以的響應完成之後才咝嗅崦娴拇a 除非你在響應事件的過程中寫代碼另外再開啟線程來處理,但這樣做就沒有意義了。
用户名:boblaw 得分:0 时间:2007-11-27 15:36:53
現在想想,觸發一個事件,必然會等事件被響應完成後才繼續咝嗅崦娴拇a,不需要考慮你所說的這個問題啊。
難道你是在響應事件的過程中使用了多線程?能否大概看下你觸發事件的代碼,以及響應事件的代碼?
用户名:woshishei 得分:0 时间:2007-11-27 15:06:20
不好意思,我说的10000个是指很多,而不是确定的某个数。 因为这是一个仿真程序。对象数量实际上是不确定的,也就是说,有的可能会响应,而有的不会。 关键的问题在于,主线程如何等待第一个事件被所有对象响应之后再继续raise第二个事件。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |