我正在为工作开发一个WF4.5服务,它在工作流程中使用延迟活动。工作流程托管在AppFabric中(在Visual Studio中进行本地测试)。我在服务中设置了web.config,AppFabric设置为使用自定义配置。以下是工作流程相关部分的图像:
从图像中获取的点是延迟之前的活动(确定通信)确实运行,并且我有可验证的证据。我也知道延迟活动后的UpdateRejectionInfo没有运行(在运行工作流时通过自定义活动中的断点验证)。
我尝试在DetermineCommunication活动和延迟活动之间添加一个持久活动,它确实保存到我正在查找的数据库中,所以我知道该服务对数据库具有写权限。
以下是该服务的web.config的行为部分:
<behaviors>
<serviceBehaviors>
<behavior>
<sqlWorkflowInstanceStore
connectionString="SERVER=hq-sql02\oculusdev;Database=EAA;Trusted_Connection=yes"
hostLockRenewalPeriod="00:00:30"
runnableInstancesDetectionPeriod="00:00:30"
instanceCompletionAction="DeleteNothing"
instanceLockedExceptionAction="AggressiveRetry"
instanceEncodingOption="GZip"/>
<workflowIdle timeToPersist="00:00:20" timeToUnload="00:00:30"/>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
任何形式的帮助都会很棒。
答案 0 :(得分:2)
好的。因此,这个问题的答案远远超出了延迟活动,并进入我正在使用的其他技术,我甚至没有提到。
TL; DR: 我没有设置我的实体框架对象来禁用延迟加载。因此,在序列化数据时,抛出了一个我从未见过的异常,它会使工作流崩溃。
长版: 将数据持久保存到数据库时,程序会尝试序列化工作流范围中的所有对象。这对于标准C#对象来说是正常的,但是当它们变成复杂对象时,序列化变得更加复杂。
为了便于技术,我在我的项目中使用Entity Framework(数据库优先)来传递和保存数据库实体。当实体框架实体被序列化时,它们会尝试获取可用的所有信息。井实体框架有这种延迟加载数据的想法,所以如果从数据库中获取实体,并且您希望更深层次(即通过外键关系),它将返回并查询数据库以获取该信息。从数据库中获取实体的一种常用方法是获取实体,然后通过使用短期使用块来切断数据库连接。
如果您决定使用短期使用块(我喜欢称为单例实体),并且您没有关闭延迟加载,那么当程序尝试序列化实体时,它将开始请求所有在初始请求中未获取的额外数据。如果已退出使用块,则数据库连接将不可用,并且将引发异常。
我没有捕获内置活动正在抛出的异常,因此它看起来并没有真正失败。