无需“持久性服务”即可管理工作流生命周期

时间:2010-02-11 19:06:53

标签: .net workflow workflow-foundation

我现在正在使用Windows WF来获取状态机的简单方法。事实上,我甚至没有使用状态机,我正在使用顺序工作流程。最终,我会抛弃WF而不是其他东西,但由于我已经有了代码,我需要让Abort,Suspend和Resume方法正常工作。

我的应用程序生成一个线程,然后生成另一个拥有WorkflowInstance的线程。我的GUI中有Abort,Pause和Resume按钮,它们最终分别调用WorkflowInstance的Abort,Suspend和Resume方法。

问题在于,当我这样做时,我会得到一个非常大且可怕的MessageBox,上面写着:

工作流托管环境没有工作流实例上的操作所需的持久性服务

以及一个很好的堆栈跟踪和所有。现在,我在Pro WF by Bruce Bukovics中查找了这些方法,他的一个例子调用了这些方法,并没有提到“持久性服务”。但是,他的示例调用属于WorkflowRuntime的范围,即他称之为:

using(WorkflowRuntimeManager manager = new WorkflowRuntimeManager(new WorkflowRuntime("WorkflowRuntime")))
{
  manager.WorkflowRuntime.StartRuntime();
  WorkflowInstanceWrapper instance = manager.StartWorkflow(typeof(SharedWorkflows.Workflow1), null);
  instance.Suspend("Manually suspended");
  instance.Resume();
  waitHandle.WaitOne();
}

在我的应用程序中,我将WorkflowRuntime实现为单例,因为我在创建WorkflowRuntime时发现存在巨大的内存泄漏。所以我的代码看起来像这样:

WorkflowInstance instance = WorkflowRuntimeSingleton.Instance.workflow_runtime.CreateWorkflow(typeof(SharedWorkflows.Workflow1), null);
instance.Start();
instance.Suspend("Manually suspended");
instance.Resume();
waitHandle.WaitOne();

现在,如果我如上所示调用Suspend and Resume,它可以正常工作。但是,如果我通过GUI发出调用,它会抱怨持久性服务。

鉴于这些信息,并且我不想仅仅为了获得这三个功能而建立数据库,我想知道我需要做些什么来使这项工作。我最好的猜测是,WF不喜欢从一个单独的线程控制。如果是这种情况,是否有一种好方法可以使调用看起来好像是从同一个线程发出的?

以下是我提出的一些可能的解决方案,但我确信这里的某个人有更好的方式来做这件事。

  1. WF通过GUI界面查看中止/暂停/恢复(似乎真的很蹩脚)
  2. 将WaitOne()替换为WaitAny(),并将GUI调用到拥有工作流的对象中,设置AutoResetEvent。 WaitAny()允许继续执行,然后我的代码可以检查用户按下哪个按钮。这需要包含在循环中,以便我们可以再次等待,直到用户单击Abort,或者直到WF完成。
  3. 使用布尔标志基本上做#2正在做的事情。
  4. 看看SO上是否有人知道如何让这个电话神奇地进入正确的线程:)
  5. 任何见解或意见都会非常感激!

3 个答案:

答案 0 :(得分:5)

创建持久性数据库并不是什么大不了的事。实际上,它会帮助您解决内存问题,因为它会暂停超过给定时间段(暂停内存)的工作流。以下链接可帮助您创建数据库并在工作流程中使用它:http://msdn.microsoft.com/en-us/library/ms735722(VS.85).aspx

在链接中,它提到更改您的app.config。我没有这样做。相反,我在代码中添加了服务。像这样:

//Add the persistence service
WorkflowPersistenceService persistenceService = new SqlWorkflowPersistenceService(
    DBConnections.PersistenceService,
    true,
    TimeSpan.MaxValue,
    new TimeSpan(0, 0, 15));
m_WorkflowRuntime.AddService(persistenceService);

编辑:Another helpful link

答案 1 :(得分:1)

SQL Server Compact不起作用,因为CE不支持存储过程,这些存储过程是默认持久性DB创建脚本的一部分,并由SQL Persistence Service调用。 CE旨在将引擎嵌入应用程序中。数据库文件将与SQL Server Express一起使用,其中引擎在单独的进程中运行,但您可以指向DBF文件,而不是连接到已连接到引擎的数据库。

通过您的问题/回复,听起来您不希望使用其他实例(共享工作流程)调用使用该应用程序实例创建的工作流程。另一种可能性是不使用SQL版本的持久性服务。工作流持久性服务的示例(可能不完整,不确定)基于将工作流直接序列化到http://msdn.microsoft.com/en-us/library/ms741725.aspx的文件。我不知道它是否支持您的所有需求,但由于它包含来源,您可以调整它。

答案 2 :(得分:0)

我发布这个作为答案,以便我可以获得不错的格式。我已经按照Gabriel的回答,我正在尝试配置数据库。我有几个问题。

所有链接都提到使用Microsoft SQL Server查询分析器创建数据库,但我没有。相反,我去了VS2008中的服务器资源管理器,右键单击数据连接 - >创建新的SQL Server数据库。我使用了Windows身份验证,并从服务器的下拉列表中选择了我的计算机。

我希望能够使用相同的数据库文件在多个系统上运行此代码。为什么我不能在这里指定 localhost

关于上述问题,如果我改为使用数据连接创建新数据库 - >添加连接,我可以创建一个本地数据库文件,我可以将其包含在我的解决方案中,并可能从PC移动到PC。这可能是正确的方法,但

使用“Microsoft SQL Server Compact 3.5”和“Microsoft SQL Server数据库文件”之间的主要区别是什么?两者都允许我创建一个文件。我更喜欢Compact选项,因为我不需要使用密码,但我不知道是否需要在Database File选项不需要的另一台计算机上安装其他特殊服务。

继续,然后我必须执行SQL查询以生成工作流持久性存储的表。根据链接页面,这个位置是:

%WINDIR%\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\<language>\SqlPersistence_Schema

由于我没有查询分析器,我认为从VS2008执行查询应该运行得很好。如果我将SQL复制并粘贴到查询窗口中,我会收到此错误对话框:

Query Definitions Differ

The following errors were encountered while parsing the contents of the SQL pane:
The Set SQL construct or statement is not supported.

接下来是:

SQL Execution Error.

Executed SQL statement: -- Copyright (c) Microsoft Corporation. All rights reserved.

SET NOCOUNT ON

--
-- ROLE state_persistence_users
--
declare @localized_string_AddRole_Failed nvarchar(256)
set @localized_string_AddRole_Failed = N'Failed adding the "state_per...
Error Source: .Net SqlClient Data Provider
Error Message: Incorrect syntax near the keyword 'if'.
Incorrect syntax near 'GO'.
Incorrect syntax near the keyword 'CREATE'.
Incorrect syntax near the keyword 'IF'.
Incorrect syntax near 'GO'.
Incorrect syntax near the keyword 'CREATE'.
Incorrect syntax near the keyword 'CREATE'.
Incorrect syntax near the keyword 'DBCC'.
Incorrect syntax near ')'.

有没有人知道我可以尝试创建持久性存储的其他方法?

相关问题