目前,我有一个大数量的计算(方法的呼吁)居住在队列即将运行顺序。每个计算将会使用一些高等待时间的服务(网络、磁盘...).

我要使用单协同程序允许下一个计算计算中排队继续,而以前的计算是等待高等待时间的服务返回。但是,我宁愿不取决于单协同程序.

是否有一个设计图案,这是可实现的纯C#这将使我能够处理额外的计算,同时等待高等待时间的服务来回报?

感谢

更新:

我需要执行数量巨大(>10000)的任务,每项任务将能使用一些高等待时间的服务。在窗户你不可能创造那么多线程。

更新:

基本上,我需要一个设计图案模拟的优点(如下)的tasklets在Stackless Python(http://www.stackless.com/)

  1. 巨大的任务
  2. 如果任务区块的下一个任务在队列中的执行
  3. 没有浪费的周期的cpu
  4. 最小的开销之间的切换任务
有帮助吗?

解决方案

你可以模拟的合作microthreading使用类型.不幸的是这不会与阻止Api,所以你需要找到Api,你可以投票,或有回调,您可以使用的信号。

考虑的一个方法

IEnumerable Thread ()
{
    //do some stuff
    Foo ();

    //co-operatively yield
    yield null;

    //do some more stuff
    Bar ();

    //sleep 2 seconds
    yield new TimeSpan (2000);
}

C#编译器,将展开这个进入一个国家机器,但外表是一个合作microthread.

图案是相当简单的。你实现"计划程序",保持一个列表中的所有活动IEnumerators.因为它的周期,通过该列表中,"运行",每一个使用MoveNext().如果值的MoveNext是虚假的,该线已经结束,该调度程序将其从名单。如果这是真的,那么该调度程序的访问目前的属性确定的当前状态的螺纹。如果它是一个时间范围,线希望睡觉和调度搬到一些队列,可以刷新回到主要的列表中时睡眠时间跨度已经结束。

你可以使用其他返回的对象来实现其它信号机制。例如,限定某种线程如果螺的产量这些中的一个,它可以移动到一个排队等候,直至处理的是暗示.或者你可以支持WaitAll通过产生一系列等待处理。你甚至可以实施的优先事项。

我做了一个简单的实施这个计划程序在有关150LOC但我没有轮到博客的代码。这是我们的PhyreSharp PhyreEngine包装机(而不是公开的),在那里它似乎运作得很好,控制了几百人物在我们的一个演示。我们借来的概念从Unity3D引擎--他们有一些网上文件,解释它从用户的观点。

其他提示

我建议你使用 线的游泳池 要执行多任务从你的队列,一次在易于管理的批次使用一个列表中的活动任务的饲料关闭的任务的队列。

在这种情况下,你的主要工作人员的线最初将pop N任务的队列入的活动任务的列表中被分派到该线的游泳池(最有可能的使用 用queueuserworkitem),其中N代表一个易于管理的数额不会超负荷的线的游泳池,沼泽你应用程序下线调度和同步的费用,或吸光了可用的存储器由于联合I/O存储器开销的每一个的任务。

每当某个任务的信号完成的工作线,可以将其从该活动的任务清单,并添加下一个从你的队的任务得以执行。

这会让你有一个滚动的组N任务从你的队列。你可以操纵N影响的性能特点并找到什么是最好的你的特殊情况。

因为你是最终的瓶颈,通过操作的硬件(盘I/O和网络I/O,CPU)我想象越小越好。两个线的游泳池任务的工作于磁盘I/O最有可能不执行的速度比一个。

你也可以实现的灵活性的规模和内容的活动任务名单由限制于一定数量的特定类型的任务。例如,如果你正在跑步机上有4个核心,你可能会发现,最高执行的配置四个中央处理器-往任务同时运行着一个磁盘上限的任务和网络的任务。

如果你已经有一个任务分类为一个盘IO任务中,你可以选择等,直到它完成之前添加另一个磁盘IO任务,并且你可以选择安排一个中央处理器-往或网络的约束的任务的同时。

希望这个意义!

PS:你有任何的依赖关系的任务?

你绝对应该检查出来的 并发和运行时的协调.他们其中一个样品描述了到底是什么你在说什么:你打电话给长期延迟的服务,并CCR有效地允许其他一些任务的运行,而你等着。它可以处理数量庞大的任务,因为它不需要产生一个线程的每一个,尽管它将会使用你所有的核心如果你问它。

这不是个常规的多使用螺纹处理?

看看模式,例如反应堆 在这里,

写入使用 异步IO 可能是足够的。

这可能导致nasy,难以调试代码没有强有力的结构在设计。

你应该看看这个:

http://www.replicator.org/node/80

这应该做的正是你想要的。它是一个黑客,虽然。

一些更多的信息,关于"反应性"模式(如通过另一张海报)相对于一项执行中。网;aka"皇宫的事件"

http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html

-Oisin

事实上,如果使用一个线程的任务,你将失去的游戏。想想为什么Node.js 可以支持大量的边的连接.使用几号的线异步IO!!!异步和等待功能可以帮上这个。

foreach (var task in tasks)
{
    await SendAsync(task.value);
    ReadAsync(); 
}

SendAsync()以及提升()都是伪造的功能的异步IO呼吁。

任务并行 也是一个很好的选择。但我不确定是哪一个速度更快。你可以测试他们两个 在你的情况。

是的你当然可以。你只是需要建立一个调度的机制,将回调一个lambda提供和进入队列中。所有代码我写在统一使用这种方法我永远不会使用的协同程序.我包裹的方法,利用协同程序如WWW的东西,刚刚摆脱它。在理论上,协同程序可更快,因为这减少了开销。实际上,他们介绍新的语法以一种语言做一个相当简单的任务,而且你不能跟这堆跟踪正确上的错误中的一个共同惯例,因为所有的你会看到的是-"下一步"。你就必须随后实施的能力运行任务的队列中的另一个线程。然而,平行的职能。净和你会基本上写类似的功能。它不会的许多行代码真的。

如果有人有兴趣,我会发送代码,不要它在我身上。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top