2011-07-27 57 views
2

我想要一个可序列化的继续,所以我可以在等待新事件时将异步工作流程腌制到磁盘。当异步工作流程正在等待let!时,它将被保存起来,同时记录下需要唤醒的内容。除了任意内存IAsyncResult(或Task<T>等),它必须是,例如,传入消息的过滤标准以及延续本身。没有语言支持延续,这可能是一个壮举。但是用计算表达式来处理明确的CPS转换,它可能不会太棘手,甚至可能更高效。有没有人处理过这样的方法?继续:我可以序列化F#异步工作流或C#异步函数的继续吗?

+0

你能举一个例子来描述你在找什么吗? – Ankur

+0

'async {let! x = GetSimulationStartTime();让! y = GetSimulationStopTime();返回! y-x}',其中start和stop可能相隔几天,而且我不想明确地为状态机建模'type AgentState = WaitingForStart | WaitingForEnd |已完成' –

+0

AFAIK甚至没有即时可用的选项来序列化Qutoations/Expressions - 没有办法在延续的一般情况下获得此信息(您可能会在关闭中捕获很多信息)。试想一下 - 无论如何,您都需要一种序列化每个对象的方法。如果你真的需要它,你可以自己实现它(你*可以*自己重写异步工作流,选择将ISerializable等待状态保存到磁盘) - 或者如其他答案中提到的那样查看WF。 – Carsten

回答

1

你或许可以使用MailboxProcessorAgent类型作为接近你想要的方式。您可以使用agent.PostAndAsyncReply超时检索当前的AgentState。如上所述,你需要让你传递的对象可序列化,但是即使代表也是可序列化的。虽然内部结构与async计算无​​关。计算只会允许您以非阻塞的方式与程序中的各种代理进行交互。

Dave Thomas我一直在研究一个名为fracture-io的库,它将提供一些用于处理代理的开箱即用方案。我们还没有讨论过这个确切的场景,但我们可以看看在...中进行烘焙或者进行提交。 :)

我也注意到你用callcc标记了你的问题。我将该运算符的样本发布到fssnip,但Tomas Petricek很快就posted an example了解如何轻松地使用async进行计算。所以我不认为callcc是这个问题的一个有用的解决方案。如果您不需要async,您可以在FSharpx中查看Continuation模块和callcc运营商。

+0

既然'MailboxProcessor' /'Agent'确实是这里的主意,我很鼓舞人心,但我承认我不太关注。代理人的内部状态必须作为委托人序列化(如你所注意的那样) - 再次唤醒它的标准(即其等待的消息)。 –

+0

所以你需要一些方法来检查每个项目,是否正确?这应该不难。你基本上遵循CanExecute和Execute委托的命令模式。我会和戴夫一起去看看我们是否能尽快完成这项工作。 – 2011-09-22 00:06:46

+0

如果我可以完全理解它,我很乐意与你们一起努力。虽然基本的弱点很可能是序列化委托意味着没有工作流可以持续更长的时间比应用程序的新部署,因为延续的结构可能会完全改变。 –

0

你看过Windows Workflow Foundation吗?

http://msdn.microsoft.com/en-us/netframework/aa663328.aspx

这可能是你想要的技术,假设事件/消息抵达小时/天/周时期,你序列化到磁盘,以避免同时使用内存/线程。 (或者你为什么要这样做?)

+2

也许太仓促判断,但我对猫和XML过敏。这些工作流程更可能持续数秒或数分钟,但几小时和几天将会很常见。在许多情况下,每个事件都要做的工作很少,但总的“状态机”非常复杂,只需使用异步工作流即可,简单的编程而不是手动构建的状态机或XML legos会很好。另外,我不介意在单声道下运行。 –

+0

在我看来,“工作流程”一词不适合异步。我希望只在执行一些我想异步执行的IO操作时使用异步,而不是使用它们实现“工作流”,因为您可以使用其他更好的抽象来表示工作流。 – Ankur

+1

我从来没有真正使用过Workflow Foundation,但我想知道是否可以在包装Workflow Foundation的F#中编写自定义计算表达式构建器,可能不需要XML? –