WF 4 OnUnhandledException 未命中

WF 4 OnUnhandledException not hit

我创建了一个自定义 activity,其中包含另一个 Activity 作为 Body。

    [Browsable(false)]
    public Activity Body { get; set; }

    protected override void Execute(NativeActivityContext context)
    {
        ActivityInstance res = context.ScheduleActivity(Body, new CompletionCallback(OnExecuteComplete), OnFaulted);
    }

    private void OnFaulted(NativeActivityFaultContext faultContext, Exception propagatedException, ActivityInstance propagatedFrom)
    {
        throw new Exception(propagatedException.Message);
    }

在主体执行期间抛出异常时,将命中 OnFaulted 的 ma 处理程序。

我的执行从调用 WorkflowApplication class 的静态方法 运行 开始。我的 WorkflowApplication 实例有一个与 OnUnhandledException 事件关联的处理程序。

 instance.OnUnhandledException +=
                       delegate(WorkflowApplicationUnhandledExceptionEventArgs args)
                    {
                        Console.WriteLine(args.ExceptionSource);
                        waitEvent.Set();
                        return UnhandledExceptionAction.Cancel;
                    };

但是,无论在主体中托管的 Activity 执行时发生什么,我都无法访问上面定义的处理程序。我认为如果我从 OnFaulted 抛出异常,我将能够将流程重定向到 OnUnhandledException 但我错了。有什么想法吗?

我需要这个来集中我的错误,检查它们并相应地显示消息。我还需要一种方法来停止执行等等,我不想在整个应用程序中定义处理程序。有什么办法可以做到这一点吗?

正如 Will 所建议的那样,我将 post 我所做的来处理我的场景。

基本上,在我的习惯 activity 中,我主持了一个分配:

    [Browsable(false)]
    public Activity Body { get; set; }

    Activity System.Activities.Presentation.IActivityTemplateFactory.Create(System.Windows.DependencyObject target)
    {
        return new Assignment()
        {
            Body = new Assign() { DisplayName = "" }
        };
    }

我已将此代码添加到我的执行方法中:

ActivityInstance res = context.ScheduleActivity(Body, new CompletionCallback(OnExecuteComplete), OnFaulted);

我试图通过给一个数组一个负值作为索引来运行这个赋值,然后抛出了一个异常。这以某种方式结束了我的执行,但没有命中我的 WorkflowApplication 实例的事件处理程序。

这是执行正文时作为回调给出的方法(在我们的例子中是 Assign activity ):

    private void OnFaulted(NativeActivityFaultContext faultContext, Exception propagatedException, ActivityInstance propagatedFrom)
    {
        faultContext.HandleFault();
        CommunicationExtension ce = faultContext.GetExtension<CommunicationExtension>();

        ITextExpression toTextExpression = (propagatedFrom.Activity as Assign).To.Expression as ITextExpression;

        string valueTextExpression = string.Empty;
        if ((propagatedFrom.Activity as Assign).Value != null)
        {
            if ((propagatedFrom.Activity as Assign).Value.Expression != null)
                valueTextExpression = (propagatedFrom.Activity as Assign).Value.Expression.ToString();
        }


        if (ce != null)
        {
            ce.AddData(string.Format("{0} found on Assignment definition [{1} = {2}]", propagatedException.Message, toTextExpression.ExpressionText, valueTextExpression));
        }
    }

诀窍是调用:

 faultContext.HandleFault();

并使用 CommunicationExtension 允许我在 GUI 中显示错误。

此 class 的代码很简单:

public class CommunicationExtension
{

    public List<string> Messages { get; set; }

    public CommunicationExtension()
    {
        Messages = new List<string>();
    }

    public void AddData(string message)
    {
        if (string.IsNullOrEmpty(message))
            return;
        Messages.Add(message);
    }
}

使用此添加扩展名:

CommunicationExtension ce = new CommunicationExtension();
instance.Extensions.Add(ce);

其中 instance 是我的 WorkflowApplication 实例。

我了解到,对于工作流应用程序的每个实例,我们都有一个扩展实例 class。所以我可以从我所有的自定义活动中发送这样的消息,以显示它们的状态。

我希望这个场景也能帮助到其他人。