2

我正在编写一个自定义 Windows Workflow Foundation 活动,它异步启动一些进程,然后在异步事件到达时唤醒。

我发现的所有示例(例如Kirk Evans的示例)都涉及自定义工作流服务,该服务完成大部分工作,然后将事件发布到活动创建的队列。主要原因似乎是发布事件的唯一方法[在非 WF 线程中工作]是 WorkflowInstance.EnqueueItem,并且活动无权访问工作流实例,因此它们无法发布事件(来自我接收异步操作结果的非 WF 线程)。

我不喜欢这种设计,因为这会将功能分成两部分,并且需要在添加新活动类型时向主机添加服务。丑陋。

所以我编写了以下通用服务,我从活动的异步事件处理程序中调用它,并且可以被各种异步活动重用(省略错误处理):

class WorkflowEnqueuerService : WorkflowRuntimeService
{
    public void EnqueueItem(Guid workflowInstanceId, IComparable queueId, object item)
    {
        this.Runtime.GetWorkflow(workflowInstanceId).EnqueueItem(queueId, item, null, null);
    }
}

现在在活动代码中,我可以获得并存储对此服务的引用,启动我的异步操作,当它完成时,使用此服务将事件发布到我的队列。这样做的好处 - 我将所有特定于活动的代码保留在活动中,并且我不必为每种活动类型添加新服务。

但是看到官方和互联网示例这样做会专门提供不可重用的服务,我想检查这种方法是否可以,或者我在这里制造了一些问题?

4

2 回答 2

1

这里有一个关于工作流持久性的潜在问题。

如果您创建长期运行的工作流,这些工作流在数据库中持久保存到运行时将能够重新启动,这些工作流不会重新加载到内存中,直到有一些外部事件重新加载它们。在那里,他们负责自己触发事件,但在重新加载之前不能。我们有一个陷阱 22 :-(

正确的方法是使用外部服务。虽然这可能感觉像是将代码分成两个地方,但实际上并非如此。原因是工作流负责大局,IE应该做什么。运行时服务负责实际实现或应该如何完成。这样,您就可以在不更改原因和时间部分的情况下更改方式。

于 2009-01-13T14:22:23.713 回答
0

后续行动——无论出于何种原因,为什么“应该”使用服务来完成,这将由 .NET 4.0 直接支持,它为 Activity 启动异步工作提供了一种干净的方式,同时暂停了活动。

有关详细信息,请参阅 http://msdn.microsoft.com/en-us/library/system.activities.codeactivitycontext.setupasyncoperationblock(VS.100).aspx

于 2009-06-22T00:37:15.400 回答