2010-08-13 59 views
8

有什么办法让委托在特定线程上运行?在特定线程上调用委托C#

说我有:

CustomDelegate del = someObject.someFunction; 
Thread dedicatedThread = ThreadList[x]; 

我能有一个一致的背景下长期运行的线程并调用我自己的代表,每当我需要它。它必须每次都是相同的线程。

[编辑]

为什么我想这是一个专门的线程的原因是时间是我INTEN在其上运行的委托后y毫秒挂起线程,并继续当我运行的线程另一位代表就此。我看到这是不可能的。我将有一个委托队列,让线程的主函数从中读取并运行。

为了澄清一个具体的例子,我有一个玩家线程的游戏系统。我希望每个playerthread都能为其上的游戏事件运行事件处理程序。如果事件处理程序花费太多时间,我希望能够暂停该特定播放器,直到下一个事件挂起其线程为止。

因此,有一个专用的线程可以运行多个事件处理程序,我可以暂停某个特定的玩家的AI,以防它被窃听或时间过长。

回答

3

我认为最好的解决方案是使用Task对象并将它们排队到运行单个线程的StaThreadScheduler

或者,您可以使用ActionThread中的Nito.Async创建一个具有Action代表的内置队列的正常线程。

但是,这些都不能直接解决另一个需求:“暂停”一个动作并继续执行另一个动作的能力。要做到这一点,你需要在每个动作中都撒上“同步点”,并有一种方法来保存它的状态,重新排列它,并继续下一个动作。

所有这些复杂性都非常接近线程调度系统,所以我建议退后一步并做更多的重新设计。您可以允许每个动作排队到ThreadPool(我建议每个动作都是Task对象)。你仍然需要撒上“同步点”,但不是保存状态并重新排队它们,而只需暂停(阻止)它们。

+0

谢谢你指出ActionThread,看起来非常有用。我需要封装外部代码,在线程中我几乎没有任何控制权。我所拥有的只是代表外部代码。如果我可以确保该对象在一个特定的线程中,我可以通过暂停该线程来“暂停”该对象。我不认为线程池将允许我很好地“暂停”对象。 – Raynos 2010-08-14 08:10:39

+0

警告:通过挂起/恢复线程可能(甚至可能)意外造成死锁。如果可能,请更改外部代码。如果这是不可能的,那么考虑使用线程优先级而不是挂起/恢复。 – 2010-08-14 10:23:30

1

通常,我会建议只使用线程池或BackgroundWorker类 - 但这些不能保证任何特定线程上都会发生工作。目前还不清楚为什么你关心哪个线程运行的作品,但假设它确实有关系...

你将不得不通过Delegate对象通过某种共享内存,如队列。后台线程必须观察这个队列,并在它们存在时将其取出,然后执行它们。

如果事实证明,线程池是可以接受的运行你的代码,你总是可以使用委托的BeginInvoke方法可以这样做:

// wrap your custom delegate in an action for simplicity ... 
Action someCode =() => yourCustomDelegate(p1, p2, p3, ...); 
// asynchronously execute the currying Action delegate on the threadpool... 
someCode.BeginInvoke(someCode.EndInvoke, action); 
2

不幸的是真的有什么内置做到这一点在任何通用线程上。您可以通过创建一个包装一个线程并实现的类来实现此目的。一个简单的方法是在LBushkin提到的专用线程上创建一个事件处理队列。我建议使用Queue<Action>类并直接调用Action委托。您可以使用匿名委托操作完成您需要的大多数任务。

最后,就像警告一样,我建议您在专用线程上使用Semaphore或EventWaitHandle,而不是Thread.Sleep。当它不必要时,它肯定比一次又一次地执行你的后台循环更友好。

+0

谢谢,我打算一遍又一遍地运行后台循环。我会考虑一个事件等待处理程序 – Raynos 2010-08-13 22:40:20

+1

我同意关于'Thread.Sleep'的警告;然而,操作应该实现'SynchronizationContext'而不是过时的'ISynchronizeInvoke'。 – 2010-08-14 01:21:16

0

对于您创建的线程,只能在创建它们时指定ThreadStart委托。没有规定将一个不同的委托注入到创建的线程中。线程池的不同之处在于,它允许您将代表提交给代表您开始的以前创建的线程。

目前尚不清楚您尝试解决什么问题。你试图通过在一个线程上运行多个委托来完成(或避免)什么?