我们正在努力将WF与多个跟踪参与者一起使用,这些参与者基本上会收听不同的查询 - 一个用于活动状态,一个用于自定义tracknig记录,这是CustomTrackingRecord的子类。
问题是我们可以单独使用TrackingParticipants,但不能同时使用它们 - 我们永远不会从CustomTrackingRecord获取子类,而是使用CustomTrackingRecord。
如果我将bopth查询放入一个TrackingParticipant然后处理每个签名,那么两者都可以完美地工作(这表明错误不是我们抛出它们的地方)。
合并后的代码是:
public WorkflowServiceTrackingParticipant ()
{
this.TrackingProfile = new TrackingProfile()
{
ActivityDefinitionId = "*",
ImplementationVisibility = ImplementationVisibility.All,
Name = "WorkflowServiceTrackingProfile",
Queries = {
new CustomTrackingQuery() { Name = "*", ActivityName = "*" },
new ActivityStateQuery() {
States = {
ActivityStates.Canceled,
ActivityStates.Closed,
ActivityStates.Executing,
ActivityStates.Faulted
}
},
}
};
}
当使用两个TrackingParticipants时,我们有两个TrackingProfile(具有不同的名称),每个都有一个查询。
在track方法中,当使用两个单独的行时:
protected override void Track(TrackingRecord record, TimeSpan timeout)
{
Console.WriteLine("*** ActivityTracking: " + record.GetType());
if (record is ActivityBasedTrackingRecord)
{
System.Diagnostics.Debugger.Break();
}
永远不会导致调试器命中,当只使用一个跟踪我们的CustomTrackingRecord子类(ActivityBasedTrackingRecord)时,它就可以工作。
其他人都知道这个吗?目前我们已将两个TrackingParticipants合二为一,但这有不好的副作用,我们无法动态扩展日志记录的可能性,我们很乐意。这是世界自然基金会的某个已知问题吗?
使用的版本:4.0 Sp1功能更新1。
答案 0 :(得分:2)
我想我遇到了完全相同的问题。 由于扩展机制的限制,会发生此问题。每个工作流实例每个扩展类型只能有一个实例(根据Microsoft的文档)。有趣的是,可以将一个相同类型的多个实例添加到一个工作流的扩展中 - 在TrackingParticipant派生的情况下 - 导致奇怪的行为,因为只有一个跟踪配置文件用于相应类型的所有参与者,但是它们的所有覆盖都是调用Track方法。 有一个(imho)丑陋的解决方法:从TrackingParticipant为每个任务派生一个新的参与者类(task1,task2,logging ...)
此致 雅各布
答案 1 :(得分:0)
我认为这个问题不是由扩展机制引起的,因为DerivedParticipant 1 和DerivedParticipant 2 不是同一类型(WF内部只是在基础上使用多态性类)。
我在同一个问题上运行,我的 Derived1 正在跟踪其个人资料中未描述的记录。
Derived1.TrackingProfile.Name 为"Foo"
, Derived2.TrackingProfile.Name 为null
我将名称从null
更改为"Bar"
,并且按预期工作。
这是一个WF内部参考代码,描述了如何选择配置文件
// System.Activities.Tracking.RuntimeTrackingProfile.RuntimeTrackingProfileCache
public RuntimeTrackingProfile GetRuntimeTrackingProfile(TrackingProfile profile, Activity rootElement)
{
RuntimeTrackingProfile runtimeTrackingProfile = null;
HybridCollection<RuntimeTrackingProfile> hybridCollection = null;
lock (this.cache)
{
if (!this.cache.TryGetValue(rootElement, out hybridCollection))
{
runtimeTrackingProfile = new RuntimeTrackingProfile(profile, rootElement);
hybridCollection = new HybridCollection<RuntimeTrackingProfile>();
hybridCollection.Add(runtimeTrackingProfile);
this.cache.Add(rootElement, hybridCollection);
}
else
{
ReadOnlyCollection<RuntimeTrackingProfile> readOnlyCollection = hybridCollection.AsReadOnly();
foreach (RuntimeTrackingProfile current in readOnlyCollection)
{
if (string.CompareOrdinal(profile.Name, current.associatedProfile.Name) == 0 && string.CompareOrdinal(profile.ActivityDefinitionId, current.associatedProfile.ActivityDefinitionId) == 0)
{
runtimeTrackingProfile = current;
break;
}
}
if (runtimeTrackingProfile == null)
{
runtimeTrackingProfile = new RuntimeTrackingProfile(profile, rootElement);
hybridCollection.Add(runtimeTrackingProfile);
}
}
}
return runtimeTrackingProfile;
}