我在win7下运行的wf4.5和C#v4.0.30319中的自定义工作流基础跟踪参与者遇到了问题。单个跟踪参与者似乎工作可靠,但是一旦我使用第二个跟踪参与者,如果跟踪或不跟踪活动,我就变成了运气游戏。 我检查了每个可能的堆栈溢出答案,可能还有每个可用的谷歌搜索结果。
我创建了一个简单的应用程序来演示行为。
我有一个简单的代码活动:
using System;
using System.Activities;
namespace WorkflowTrackingTestApp
{
public sealed class CodeActivity1 : CodeActivity
{
public InArgument<string> Text { get; set; }
protected override void Execute( CodeActivityContext context )
{
Console.WriteLine( "executing code activity " + typeof( string ).Assembly.ImageRuntimeVersion );
}
}
}
它只执行打印&#34;执行代码活动和c#版本&#34;。
我有两个自定义跟踪参与者。请注意,它们都有跟踪配置文件,并且配置文件具有不同的名称,因为在另一个线程中建议这可能是问题。
namespace ActivityLibrary
{
using System;
using System.Activities.Tracking;
public class EventTrackingParticipant0 : TrackingParticipant
{
public EventTrackingParticipant0()
{
this.TrackingProfile = new TrackingProfile
{
Name = "CustomTrackingProfile0",
Queries =
{
new WorkflowInstanceQuery
{
// Limit workflow instance tracking records for started and
// completed workflow states.
States = {WorkflowInstanceStates.Started, WorkflowInstanceStates.Completed},
}
}
};
}
public Action<TrackingRecord> Received { get; set; }
protected override void Track( TrackingRecord record, TimeSpan timeout )
{
if( Received != null )
{
Received.BeginInvoke( record, BeginInvokeCallback, Received );
}
}
private void BeginInvokeCallback( IAsyncResult ar )
{
((Action<TrackingRecord>)ar.AsyncState).EndInvoke( ar );
}
}
public class EventTrackingParticipant1 : TrackingParticipant
{
public EventTrackingParticipant1()
{
this.TrackingProfile = new TrackingProfile
{
Name = "CustomTrackingProfile1",
Queries =
{
new WorkflowInstanceQuery
{
// Limit workflow instance tracking records for started and
// completed workflow states.
States = {WorkflowInstanceStates.Started, WorkflowInstanceStates.Completed},
}
}
};
}
public Action<TrackingRecord> Received { get; set; }
protected override void Track( TrackingRecord record, TimeSpan timeout )
{
if( Received != null )
{
Received.BeginInvoke( record, BeginInvokeCallback, Received );
}
}
private void BeginInvokeCallback( IAsyncResult ar )
{
((Action<TrackingRecord>)ar.AsyncState).EndInvoke( ar );
}
}
}
对于两个配置文件,代码基本相同。
现在进入主程序:
namespace WorkflowTrackingTestApp
{
using System;
using System.Activities;
using ActivityLibrary;
class Program
{
static void Main( string[] args )
{
EventTrackingParticipant0 tp0 = new EventTrackingParticipant0();
tp0.Received = tr => Console.WriteLine( "tracker0 tracking " + tr.EventTime.ToString( CultureInfo.InvariantCulture ) + " " + tr.RecordNumber);
EventTrackingParticipant1 tp1 = new EventTrackingParticipant1();
tp1.Received = tr => Console.WriteLine( "tracker1 tracking " + tr.EventTime.ToString( CultureInfo.InvariantCulture ) + " " + tr.RecordNumber );
Activity workflow1 = new CodeActivity1();
WorkflowInvoker wfInvoker = new WorkflowInvoker( workflow1 );
//add tracking participants
wfInvoker.Extensions.Add( tp0 );
wfInvoker.Extensions.Add( tp1 );
wfInvoker.Invoke( );
}
}
}
它添加了两个跟踪参与者并执行代码活动。 这是一些可能的结果:
executing code activity v4.0.30319
tracker0 tracking 08/26/2015 09:18:50 0
tracker1 tracking 08/26/2015 09:18:50 0
Press any key to continue . . .
executing code activity v4.0.30319
tracker0 tracking 08/26/2015 09:29:41 0
tracker0 tracking 08/26/2015 09:29:41 4
tracker1 tracking 08/26/2015 09:29:41 0
tracker1 tracking 08/26/2015 09:29:41 4
Press any key to continue . . .
executing code activity v4.0.30319
tracker0 tracking 08/26/2015 09:30:08 0
tracker1 tracking 08/26/2015 09:30:08 0
tracker0 tracking 08/26/2015 09:30:08 4
tracker1 tracking 08/26/2015 09:30:08 4
Press any key to continue . . .
executing code activity v4.0.30319
tracker0 tracking 08/26/2015 09:30:25 0
tracker1 tracking 08/26/2015 09:30:25 0
tracker1 tracking 08/26/2015 09:30:25 4
Press any key to continue . . .
有谁知道这可能是造成这种行为的原因。
答案 0 :(得分:2)
跟踪参与者是异步执行的,通常不在与活动执行相同的线程中。您的控制台应用程序有时会在其中一个参与者有时间执行之前退出。例如,如果添加简单 System.Threading.Thread.Sleep(1000); 在wfInvoker.Invoke()之后;你几乎总能得到所有4个处理程序。
答案 1 :(得分:1)
从
更改Track方法的实现 if( Received != null )
{
Received.BeginInvoke( record, BeginInvokeCallback, Received );
}
到
if (Received != null)
Received(record);
在这种情况下,跟踪参与者将在与活动相同的线程中执行。