如何创建自定义消息泵?我正在做一个小练习,我需要创建类似消息泵的东西。我有一个工作队列,我希望工作完全在一个线程上完成,而任何线程都可以将工作添加到队列中。队列队列;线程使用等待句柄来告诉泵有工作要做。等待处理信号;只要有工作要做,泵就会循环,然后等待信号再次启动。while(ApplicationIsRunning){while(queue.HasWork){DoWork(queue.NextWorkItem)}signal.Reset();信号.WaitOne();}每个其他线程都可以将工作添加到队列中并向等待句柄发出信号...publicvoidAddWork(WorkToDowork){queue.Add(work);信号.设置();问题是,如果工作添加的速度足够快,就会出现工作可以留在队列中的情况,因为队列检查工作和WaitHandleBetween重置,另一个线程可以将工作添加到队列中。如果不在WaitHandle周围放置昂贵的互斥锁,我将如何缓解这种情况?您可以使用BlockingCollection更轻松地实现队列,因为它将为您处理同步:publicclassMessagePump{privateBlockingCollectionactions=newBlockingCollection();publicvoidRun()//你可能想限制这一点,这样只有来自一个线程的一个调用者正在运行消息{foreach(varactioninactions.GetConsumingEnumerable())action();}publicvoidAddWork(Actionaction){动作。添加(动作);}publicvoidStop(){动作。完成添加();你不应该做一个完整的互斥体,但你可以做一个锁定语句publicvoidAddWork(WorkToDowork){queue.Add(work);锁(lockingObject){signal.Set();使用任何你想锁定对象,大多数人会说使用信号本身是个坏主意。为响应下面的@500-内部服务器错误评论,您可以在完成工作之前重置信号。下面应该保护一些东西:while(ApplicationIsRunning){while(queue.HasWork){WorkItemwi;锁(锁定对象){wi=queue.NextWorkItem;如果(!queue.HasWork){signal.Reset();}}DoWork(wi)}signal.WaitOne();这样,如果您有更多工作,内部队列将继续运行。如果没有,它会落到signal.WaitOne(),只有在没有更多工作排队时我们才会重置它。这里唯一的缺点是,如果在DoWork执行时有工作进来,我们可能会连续多次重置。您可以使用WaitOne(TimeSpan)方法,这样您就有了一个混合信号/轮询循环。基本上指定一个时间跨度最多等待1秒。这将导致任务在该竞赛中停留最多一秒钟(或您指定的任何轮询时间)或直到另一个任务被添加到您的队列中。以上就是C#学习教程:Howtocreateacustommessagepump?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
