开发者

Multiple TrackingParticipants not working, have funny side effects?

We are rying to use WF with multiple tracking participants which essentially listen to different queries - one for activity states, one for custom tracknig records which are a subclass of CustomTrackingRecord.

The problem is that we can use both TrackingParticipants indivisually, but not together - we never get our subclass from CustomTrackingRecord but A CustomTrackingRecord.

If I put bopth queries into one TrackingParticipant and then handle everythign in one, both work perfectly (which indicates teh error is not where we throw them).

The code in question for the combined one is:

public WorkflowServiceTrackingParticipant ()
{
    this.TrackingProfile = new TrackingProfile()
    {
        ActivityDefinitionId = "*",
        ImplementationVisibility = ImplementationVisibility.All,
        Name = "WorkflowServiceTrackingProfile",
        Q开发者_运维百科ueries = {
            new CustomTrackingQuery() { Name = "*", ActivityName = "*" },
            new ActivityStateQuery() { 
                States = {
                    ActivityStates.Canceled,
                    ActivityStates.Closed, 
                    ActivityStates.Executing, 
                    ActivityStates.Faulted
                } 
            },
        }
    };
}

When using two TrackingParticipants we have two TrackingProfile (with different names) that each have one of the queries.

in the track method, when using both separate, the lines:

    protected override void Track(TrackingRecord record, TimeSpan timeout)
    {
        Console.WriteLine("*** ActivityTracking: " + record.GetType());
        if (record is ActivityBasedTrackingRecord)
        {
            System.Diagnostics.Debugger.Break();
        }

never result in the debugger hitting, when using only the one to track our CustomTrackingRecord subclass (ActivityBasedTrackingRecord) then it works.

Anyone else knows about this? For now we have combined both TrackingParticipants into one, but this has the bad side effect that we can not dynamically expand the logging possibilities, which we would love to. Is this a known issue with WWF somewhere?

Version used: 4.0 Sp1 Feature Update 1.


I guess I encounterad the exact same problem. This problem occurs due to the restrictions of the extension mechanism. There can be only one instance per extension type per workflow instance (according to Microsoft's documentation). Interesting enough though, one can add multiple instances of the same type to one workflow's extensions which - in case of TrackingParticipant derivates - causes weird behavior, because only one of their tracking profiles is used for all participants of the respective type, but all their overrides of the Track method are getting invoked. There is a (imho) ugly workaround to this: derive a new participant class from TrackingParticipant for each task (task1, task2, logging ...)

Regards, Jacob


I think that this problem isn't caused by extension mechanism, since DerivedParticipant 1 and DerivedParticipant 2 are not the same type(WF internals just use polymorphism on the base class).

I was running on the same issue, my Derived1 was tracking records that weren't described in its profile.

Derived1.TrackingProfile.Name was "Foo" and Derived2.TrackingProfile.Name was null

I changed the name from null to "Bar" and it worked as expected.

Here is a WF internal reference code, describing how is the Profile selected

// 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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜