C#学习教程:在特定线程上调用Delegate假设我有:CustomDelegatedel=someObject.someFunction;线程dedicatedThread=ThreadList[x];我可以有一个一致的后台长时间运行线程并在需要时调用我自己的委托吗?每次都必须是相同的线程。[编辑]我想要它在专用线程上的原因是时间是我打算在它上面运行一个委托并在y毫秒后挂起线程,并在我运行另一个委托时恢复线程。我认为这是不可能的。我会有一个委托队列,并从中读取并运行线程的主函数。为了用一个具体的例子来说明,我有一个带有一堆玩家线程的游戏系统。我希望每个玩家线程都具有在其上运行的游戏事件的事件处理程序。如果事件处理程序花费太多时间,我希望能够通过暂停其线程来暂停该特定播放器直到下一个事件。因此,有了一个专用线程,我可以运行多个事件处理程序,并且我可以暂停特定玩家的AI,以防它被窃听或花费太长时间。我认为最好的解决方案是使用Task对象并将它们排队到运行单个线程的StaThreadScheduler。或者,您可以使用ActionThread中的ActionThread创建一个带有内置Action代理队列的普通线程。然而,这些都不能直接解决另一个需求:“暂停”一个动作并恢复另一个动作的能力。为此,您需要为每个操作添加“同步点”,并有办法保存其状态、重新排队并继续进行下一个操作。所有这些复杂性都非常接近于线程调度系统,因此我建议退后一步并进行更多的重新设计。您可以允许每个操作排队到ThreadPool(我建议每个操作都是一个Task对象)。您仍然需要使用“同步点”,但不是保存状态和重新排队,而是暂停(阻止)它们。不幸的是,任何通用线程都没有内置功能。您可以通过创建一个包装Thread并实现ISynchonizeInvoke的类来做到这一点。正如LBushkin提到的,一种简单的方法是在专用线程上创建一个事件处理队列。我建议使用Queue类并直接调用Action委托。您可以使用匿名委托操作来完成您需要的大部分任务。最后,作为警告,我建议您在专用线程上使用Semaphore或EventWaitHandle而不是Thread.Sleep。这绝对比在没有必要时一遍又一遍地做你的背景循环更友好。一般来说,我建议只使用线程池或BackgroundWorker类-但这些并不能保证工作会在任何特定线程上发生。目前尚不清楚为什么你关心哪个线程运行工作,但假设它确实有某种关系......你必须通过某种共享内存(如队列)传递Delegate对象。后台线程必须观察这个队列,在委托存在时从中提取委托,然后执行它们。如果事实证明线程池可以运行代码,您始终可以使用BeginInvoke方法来执行此操作://为了简单起见,将自定义委托包装在一个操作中...ActionsomeCode=()=>yourCustomDelegate(p1,p2,p3,...);//在线程池上异步执行curryingAction委托...someCode.BeginInvoke(someCode.EndInvoke,action);对于您创建的线程,您只能在创建它们时指定ThreadStart委托。没有规定将不同的委托注入创建的线程。线程池的不同之处在于它允许您将代理提交给它代表您启动的先前创建的线程。目前尚不清楚您要解决的问题是什么。您试图通过在一个线程上运行多个委托来试图完成(或避免)什么?这是我为在特定线程上运行某些内容而实现的模式。这样做的好处是可以在阻塞工作调用之前或之后启动特定线程。它是一个名为Watin的COM对象包装器,用于操作对上下文非常敏感的InternetExplorer实例。可以扩展它以删除Thread.Sleep(),可能使用AutoResetEvent,这在某些情况下会大大提高性能。这种模式的想法来自JustinBreitfeller、StephenCleary和LBushkin的回答。以上就是C#学习教程:在特定线程C#调用delegate分享的全部内容,如果对大家有用,还需要详细了解C#学习教程,希望大家多加关注—privateInstantiate(){BrowserQueue=newConcurrentQueue();BrowserThread=newThread(newThreadStart(BrowserThreadLoop));BrowserThread.SetApartmentState(ApartmentState.STA);BrowserThread.Name="浏览器线程";BrowserThread.Start();}privatestaticvoidBrowserThreadLoop(){while(true){Thread.Sleep(500);BrowserActionact=null;while(Instance.BrowserQueue.TryDequeue(outact)){try{act.Action();}catch(Exceptionex){}finally{act.CompletionToken.Set();}}}}publicstaticvoidRunBrowserAction(Actionact){BrowserActionba=newBrowserAction(){Action=act,CompletionToken=newManualResetEvent(false)};Instance.BrowserQueue.Enqueue(ba);ba.CompletionToken.WaitOne();}publicclassBrowserAction{publicActionAction{get;放;}=空;公共ManualResetEventCompletionToken{得到;放;}=空;}并发队列浏览器队列;本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处:
