Reputation: 2424
The following is newly created thread code that has been successfully started by my UI thread (the UI code is not here).
When I single step in debugging I do get to this code.
When the workflow that I am executing does not have any problems, the code runs to completion. But when the workflow is faulty (I am testing my code by using a faulty workflow) this code does not catch the WorkflowException
that happens during the wf.Run()
statement below.
I think I have the workflow execution exception handling code below?? Can you tell me what I am doing wrong? Thanks.
public void ThreadRun ()
{
AutoResetEvent syncEvent = new AutoResetEvent(false);
var wf = ActivityXamlServices.Load(fileInfo.FileName);
// Create the WorkflowApplication using the desired
// workflow definition.
WorkflowApplication wfApp = new WorkflowApplication(wf);
// Handle the desired lifecycle events.
wfApp.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
{
syncEvent.Set();
};
try
{
// Start the workflow.
wfApp.Run();
// Wait for Completed to arrive and signal that
// the workflow is complete.
syncEvent.WaitOne();
}
catch (Exception exception)
{
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);
// Outputs can be retrieved from the Outputs dictionary,
// keyed by argument name.
// Console.WriteLine("The winner is {0}.", e.Outputs["Winner"]);
}
};
wfApp.Aborted = delegate(WorkflowApplicationAbortedEventArgs e)
{
// Display the exception that caused the workflow
// to abort.
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)
{
// Perform any processing that should occur
// when a workflow goes idle. If the workflow can persist,
// both Idle and PersistableIdle are called in that order.
Console.WriteLine("Workflow {0} Idle.", e.InstanceId);
};
wfApp.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e)
{
// Instruct the runtime to persist and unload the workflow.
// Choices are None, Persist, and Unload.
return PersistableIdleAction.Unload;
};
wfApp.Unloaded = delegate(WorkflowApplicationEventArgs e)
{
Console.WriteLine("Workflow {0} Unloaded.", e.InstanceId);
};
wfApp.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
{
// Display the unhandled exception.
Console.WriteLine("OnUnhandledException in Workflow {0}\n{1}",
e.InstanceId, e.UnhandledException.Message);
Console.WriteLine("ExceptionSource: {0} - {1}",
e.ExceptionSource.DisplayName, e.ExceptionSourceInstanceId);
// Instruct the runtime to terminate the workflow.
// Other choices are Abort and Cancel. Terminate
// is the default if no OnUnhandledException handler
// is present.
return UnhandledExceptionAction.Terminate;
};
}
}
Upvotes: 1
Views: 2014
Reputation: 1
I think you just have to handle the OnUnhandledException event before the catch (i see you have this event handled but in your catch block).
wfApp.OnUnhandledException will let you catch the error.
Upvotes: 0
Reputation: 3744
That's cause the exception is thrown in a different thread, I think. Check this: catch exception that is thrown in different thread
The exceptions thrown in a different thread are not passed to the caller thread by default.
EDIT: I have the impression that you would like the delegates to be set before the workflow starts, is that correct? If so, do the assignments to wfApp.OnUnhandledException
and such before you do the wfApp.Run()
.
Upvotes: 3