Почему исключения рабочих процессов не перехватываются при выбросе из Cancel? - PullRequest
1 голос
/ 24 сентября 2019

Я использую Microsoft Windows Workflow Foundation в своем приложении для Windows.

Я подписался на OnUnhandledException в рабочем процессе для любого непредвиденного исключения.

Получен обратный вызов OnHandledException длявсе исключения внутри рабочего процесса, но отменить регистр .

Предположим, что вызван WorkflowApplication.BeginCancel(..., ..), который в конечном итоге вызывает отмену действий, теперь, если исключение выдается изнутри Activity (Получено из собственной деятельности) при вызове отмены, тогда Обратный вызов OnUnhandledException не получен .

Я знаю, что я все еще могу получить CancelCallBack для BeginCancel, и я могу делать то же самое, что и OnUnhandledException, однако я бы хотел воздержаться от этого.Также код более понятен, если есть стандартный протокол - (если есть исключение, независимо от того, откуда обратный вызов UnhandledException должен получить вызов).

Если это протокол, предоставленный Microsoft для Workflow, было бы здорово, если бы вы могли поделиться ссылкой на документацию, в которой упоминается этот уникальный случай отмены, или предложить, если мне нужно сделать что-то дополнительное, чтобы получить этот обратный вызов.

Ниже приведен пример кода

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Enter values for following operations");
        Console.WriteLine("c: Cancel");
        Console.WriteLine("p: Progress. This is a multiple resume operation you can press p as many times you want untill workflow is completed or aborted!!");
        Console.WriteLine("f: Finish");
        Console.WriteLine("0 i.e Zero: Exit");
        Console.WriteLine("=============================================");

        var wf = CreateWorkflow();
        string a = Console.ReadLine();
        while (a.ToString() != "0")
        {

            switch (a.ToString().ToLower())
            {
                case "c":
                    {

                        //wf.Cancel();
                        wf.BeginCancel(AsyncCallBackMethod, null);
                        break;
                    }
                case "f":
                    {
                        wf.ResumeBookmark("Finish", null);
                        Console.WriteLine("Workflow completed press 0 to exit.");
                        break;
                    }
                case "p":
                    {
                        wf.ResumeBookmark("Progress", "Hello World");
                        break;
                    }
                default:
                    {
                        Console.WriteLine("Not a valid input");
                        break;
                    }
            }
            Console.WriteLine("");
            Console.WriteLine("=============================================");
            Console.WriteLine("==============Enter next operation===========");
            a = Console.ReadLine();
        }

        Console.WriteLine("Enter to exit");
        Console.Read();
    }

    private static void AsyncCallBackMethod(IAsyncResult ar)
    {
        Console.WriteLine("Cancel callback");
    }

    static WorkflowApplication CreateWorkflow()
    {
        WorkflowApplication wfApp = new WorkflowApplication(new SampleActivity()) { SynchronizationContext = new SynchronousSynchronizationContext() };

        // Handle the desired lifecycle events.
        wfApp.Completed = delegate (WorkflowApplicationCompletedEventArgs e)
        {
            if (e.CompletionState == ActivityInstanceState.Faulted)
            {
                Console.WriteLine("Workflow {0} Terminated.", e.InstanceId);
                Console.WriteLine("Exception: {0}\n{1}",
                    e.TerminationException.GetType().FullName,
                    e.TerminationException.Message);
            }
            else if (e.CompletionState == ActivityInstanceState.Canceled)
            {
                Console.WriteLine("Workflow {0} Canceled.", e.InstanceId);
            }
            else
            {
                Console.WriteLine("Workflow {0} Completed.", e.InstanceId);
            }

            Console.Read();
        };

        wfApp.Aborted = delegate (WorkflowApplicationAbortedEventArgs e)
        {
            Console.WriteLine("Workflow {0} Aborted.", e.InstanceId);
            Console.WriteLine("Exception: {0}\n{1}",
                e.Reason.GetType().FullName,
                e.Reason.Message);
        };

        wfApp.Idle = delegate (WorkflowApplicationIdleEventArgs e)
        {
            Console.WriteLine("Workflow {0} Idle.", e.InstanceId);
        };

        wfApp.PersistableIdle = delegate (WorkflowApplicationIdleEventArgs e)
        {
            return PersistableIdleAction.Unload;
        };

        wfApp.Unloaded = delegate (WorkflowApplicationEventArgs e)
        {
            Console.WriteLine("Workflow {0} Unloaded.", e.InstanceId);
        };

        wfApp.OnUnhandledException = delegate (WorkflowApplicationUnhandledExceptionEventArgs e)
        {
            Console.WriteLine("OnUnhandledException in Workflow {0}\n{1}",
            e.InstanceId, e.UnhandledException.Message);

            Console.WriteLine("ExceptionSource: {0} - {1}",
                e.ExceptionSource.DisplayName, e.ExceptionSourceInstanceId);

            return UnhandledExceptionAction.Cancel;
        };

        wfApp.Run();

        return wfApp;
    }
}

public class SampleActivity : NativeActivity
{
    protected override sealed bool CanInduceIdle
    {
        get { return true; }
    }

    protected override void Execute(NativeActivityContext context)
    {
        Console.Write("Inside Activite Execute");
        CreateBookmarks(context);
    }

    protected override void Cancel(NativeActivityContext context)
    {
        throw new Exception("Some Exception");
    }

    private void CreateBookmarks(NativeActivityContext context)
    {
        context.CreateBookmark("Progress", OnProgressRecieved, BookmarkOptions.MultipleResume);
        context.CreateBookmark("Finish", OnCalculationFinished);
    }

    protected virtual void OnProgressRecieved(NativeActivityContext context, Bookmark bookmark, object sender)
    {
        var name = sender as string;
        if (string.IsNullOrEmpty(name))
        {
            throw new Exception();
        }
        Console.WriteLine($"On Activity Progress called. Welcome {name}");
    }

    protected virtual void OnCalculationFinished(NativeActivityContext context, Bookmark bookmark, object sender)
    {
        Console.WriteLine($"On Activity finished called.");

        context.RemoveAllBookmarks();
    }
}

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