Issue with TraceTrackingParticipant and SynchronizationContext

Jul 12, 2012 at 2:08 PM

Hello Gurus, I hope you can help!

I have a WCF service which calls into workflow via the WorkflowApplication, I need this to use the same WCF thread as we use Thread.CurrentPrincipal and also have a static instance of NHibernate.

When I use the WorkflowApplication with my own SynchronizationContext the WorkflowApplication stays on the same thread (as expected), as soon as I add the extension TraceTrackingParticipant the thread changes. Can anyone give any indication why this may be happening and how to resolve it? The TraceTrackingParticipant extension is great for finding which activity is causing the issue and i don't want to remove it.

Just to note you must have a xaml activity for the issue to show, just calling a codeactivity will work as expected.

 

Here is an example of what im trying to achieve -

    public class SyncContext : SynchronizationContext
    {
        public override void Post(SendOrPostCallback d, object state)
        {
            d(state);
        }

        public override void Send(SendOrPostCallback d, object state)
        {
            d(state);
        }
    }

    public sealed class OutputCurrentPrincipalName : CodeActivity
    {
        protected override void Execute(CodeActivityContext context)
        {
            Console.WriteLine("ThreadId - {0} IdentityName - {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentPrincipal.Identity.Name);           
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("myIdentity", ""), new string[0]);
            Console.WriteLine("ThreadId - {0} IdentityName - {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentPrincipal.Identity.Name);
            var idleEvent = new AutoResetEvent(false);
            var app = new WorkflowApplication(new Activity1());
            app.SynchronizationContext = new SyncContext();
            app.Extensions.Add(new TraceTrackingParticipant());

            app.Idle = e => idleEvent.Set();
            app.Completed = e => idleEvent.Set();
            app.Run();
            idleEvent.WaitOne();
            Console.Read();
        }
    }

<Activity mc:Ignorable="sap" x:Class="SyncContextExample.Activity1" sap:VirtualizedContainerService.HintSize="654,676" mva:VisualBasic.Settings="Assembly references and imported namespaces for internal implementation" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:local="clr-namespace:SyncContextExample" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Xml" xmlns:s3="clr-namespace:System;assembly=System.Core" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Flowchart sad:XamlDebuggerXmlReader.FileName="c:\users\grahame\documents\visual studio 2010\Projects\SyncContextExample\SyncContextExample\Activity1.xaml" sap:VirtualizedContainerService.HintSize="614,636">
    <sap:WorkflowViewStateService.ViewState>
      <scg3:Dictionary x:TypeArguments="x:String, x:Object">
        <x:Boolean x:Key="IsExpanded">False</x:Boolean>
        <av:Point x:Key="ShapeLocation">270,2.5</av:Point>
        <av:Size x:Key="ShapeSize">60,75</av:Size>
        <av:PointCollection x:Key="ConnectorLocation">300,77.5 300,127.5</av:PointCollection>
      </scg3:Dictionary>
    </sap:WorkflowViewStateService.ViewState>
    <Flowchart.StartNode>
      <FlowStep x:Name="__ReferenceID0">
        <sap:WorkflowViewStateService.ViewState>
          <scg3:Dictionary x:TypeArguments="x:String, x:Object">
            <av:Point x:Key="ShapeLocation">200,127.5</av:Point>
            <av:Size x:Key="ShapeSize">200,22</av:Size>
            <av:PointCollection x:Key="ConnectorLocation">300,149.5 300,199.5</av:PointCollection>
          </scg3:Dictionary>
        </sap:WorkflowViewStateService.ViewState>
        <local:OutputCurrentPrincipalName sap:VirtualizedContainerService.HintSize="200,22">
          <sap:WorkflowViewStateService.ViewState>
            <scg3:Dictionary x:TypeArguments="x:String, x:Object">
              <x:Boolean x:Key="IsExpanded">True</x:Boolean>
            </scg3:Dictionary>
          </sap:WorkflowViewStateService.ViewState>
        </local:OutputCurrentPrincipalName>
      </FlowStep>
    </Flowchart.StartNode>
    <x:Reference>__ReferenceID0</x:Reference>
  </Flowchart>
</Activity>

Thanks for your help.