2011-08-09 78 views
9

有没有什么办法可以抽象出某个特定委托可能执行的线程,以便我可以在调用线程上最初执行它,但是如果执行结果花费的时间超过了一定的时间?是否可以将代理的执行从一个线程移动到另一个线程执行中?

假定代理写入异步。我没有试图采用同步块并将它们移动到后台线程来增加并行性,但是我正在寻求通过避免简单操作的线程开销来提高异步执行的性能。

基本上我想知道是否有任何方式的委托或lambda的执行可以暂停,移动到另一个线程和恢复,如果我能确定明确的界限栈等

我怀疑这是可能的, 我只是好奇。

回答

3

这是可能的,但它会是尴尬和难以得到正确的。做到这一点的最好方法是使用coroutines。目前符合协程范式的.NET中唯一的机制是C#的迭代器,通过关键字yield return。你可能理论上一起攻击的东西,允许执行方法从一个线程转换到另一个。然而,这只不过是一个值得攻击的博客,但我认为这是可能的。

下一个最佳选择是继续并升级到Async CTP。这是C#中提供的一项功能,可以让您按照您的要求进行操作。建议的await关键字和一些聪明的漏洞也将包括在内,这是完美的。最终结果看起来像下面这样。

public async void SomeMethod() 
{ 
    // Do stuff on the calling thread. 

    await ThreadPool.SwitchTo(); // Switch to the ThreadPool. 

    // Do stuff on a ThreadPool thread now! 

    await MyForm.Dispatcher.SwitchTo(); // Switch to the UI thread. 

    // Do stuff on the UI thread now! 
} 

这只是许多恶人很酷的技巧,你可以用新的await关键字做之一。


实际上你可以注入的代码的执行到一个现有的线程的唯一方法是,如果目标是专门为接受一个工作项目的形式注入。

你可以看到我的回答here一个这样的尝试在模仿await关键字迭代器。 MindTouch Dream框架是另一种可能更好的变体。关键是应该可以通过一些巧妙的黑客攻击来切换线程。

+0

迷人!我一定会对'await'和Async CTP做更多的研究。我承认,当我一读回来的时候,我并没有完全理解“等待”的内容。 Wow; – devios1

+0

哇;这是光滑的。 –

2

不容易。

如果将您的委托构造为状态机,则可以跟踪状态之间的执行时间,并在达到所需阈值时,在新线程中启动下一个状态。

一个更简单的解决方案是在一个新的线程中启动它,以开始。任何不可接受的理由?

(从我的手机发布 - 我会提供一些伪代码,当我在一个真正的键盘如果需要的话)

+0

嗯,这是一个有趣的想法,我没有考虑。出于我的目的,我更感兴趣的是保持代表的格式非常简单(状态机将会过度)。我可能会最终走上使用线程池线程的路线;我只是好奇,如果有什么办法可以优化那些微不足道的操作。 – devios1

+0

是的,你只是说,在一个循环中做一堆相同的操作,FSM是矫枉过正的。但是,在这种情况下,您可以根据估计的工作负载/迭代情况估计所需的执行时间,并预先决定使用哪个线程。 –

+0

是的,我也已经做了一些思考......也许保留过去执行时间的数据库,并使用平均值做出关于它是否应该在后台线程上运行的明智决定。当然,你必须考虑做所有的指标可能需要的时间比通过在当前线程上运行得到的优化时间要长(事实上,它几乎可以保证)。所以真的成为一个有争议的问题。尽管如此,仍然有趣的想法。 – devios1

1

不,我不认为这是可能的。至少不直接与常规代表。如果你创建了一些IEnumerable,在一些工作之后产生,那么你可以手动运行它的一些迭代,然后在经过这么多次迭代之后切换到在后台线程上运行它。

ThreadPool和TPL的任务应该有足够的性能,只需总是在后台线程上运行它。除非你有一个特定的基准测试,表明使用任务会产生一堆开销,这听起来像是在试图过早地进行优化。

+0

事实上,你是对的过早优化,我很清楚它(我承认有一个过早的优化问题,哈哈)。因此,正如我所说的,为什么我没有认真对待它,更多的是出于对未来潜在改善的好奇心。 ;) – devios1

相关问题