e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
154 lines
6.8 KiB
C#
154 lines
6.8 KiB
C#
//-----------------------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
namespace System.Activities.Runtime
|
|
{
|
|
using System;
|
|
using System.Runtime;
|
|
using System.Runtime.Serialization;
|
|
using System.Security;
|
|
|
|
[DataContract]
|
|
class FaultCallbackWrapper : CallbackWrapper
|
|
{
|
|
static readonly Type faultCallbackType = typeof(FaultCallback);
|
|
static readonly Type[] faultCallbackParameters = new Type[] { typeof(NativeActivityFaultContext), typeof(Exception), typeof(ActivityInstance) };
|
|
|
|
public FaultCallbackWrapper(FaultCallback callback, ActivityInstance owningInstance)
|
|
: base(callback, owningInstance)
|
|
{
|
|
}
|
|
|
|
[Fx.Tag.SecurityNote(Critical = "Because we are calling EnsureCallback",
|
|
Safe = "Safe because the method needs to be part of an Activity and we are casting to the callback type and it has a very specific signature. The author of the callback is buying into being invoked from PT.")]
|
|
[SecuritySafeCritical]
|
|
public void Invoke(NativeActivityFaultContext faultContext, Exception propagatedException, ActivityInstance propagatedFrom)
|
|
{
|
|
EnsureCallback(faultCallbackType, faultCallbackParameters);
|
|
FaultCallback faultCallback = (FaultCallback)this.Callback;
|
|
faultCallback(faultContext, propagatedException, propagatedFrom);
|
|
}
|
|
|
|
public WorkItem CreateWorkItem(Exception propagatedException, ActivityInstance propagatedFrom, ActivityInstanceReference originalExceptionSource)
|
|
{
|
|
return new FaultWorkItem(this, propagatedException, propagatedFrom, originalExceptionSource);
|
|
}
|
|
|
|
[DataContract]
|
|
internal class FaultWorkItem : ActivityExecutionWorkItem
|
|
{
|
|
FaultCallbackWrapper callbackWrapper;
|
|
Exception propagatedException;
|
|
ActivityInstance propagatedFrom;
|
|
ActivityInstanceReference originalExceptionSource;
|
|
|
|
public FaultWorkItem(FaultCallbackWrapper callbackWrapper, Exception propagatedException, ActivityInstance propagatedFrom, ActivityInstanceReference originalExceptionSource)
|
|
: base(callbackWrapper.ActivityInstance)
|
|
{
|
|
this.callbackWrapper = callbackWrapper;
|
|
this.propagatedException = propagatedException;
|
|
this.propagatedFrom = propagatedFrom;
|
|
this.originalExceptionSource = originalExceptionSource;
|
|
}
|
|
|
|
public override ActivityInstance OriginalExceptionSource
|
|
{
|
|
get
|
|
{
|
|
return this.originalExceptionSource.ActivityInstance;
|
|
}
|
|
}
|
|
|
|
[DataMember(Name = "callbackWrapper")]
|
|
internal FaultCallbackWrapper SerializedCallbackWrapper
|
|
{
|
|
get { return this.callbackWrapper; }
|
|
set { this.callbackWrapper = value; }
|
|
}
|
|
|
|
[DataMember(Name = "propagatedException")]
|
|
internal Exception SerializedPropagatedException
|
|
{
|
|
get { return this.propagatedException; }
|
|
set { this.propagatedException = value; }
|
|
}
|
|
|
|
[DataMember(Name = "propagatedFrom")]
|
|
internal ActivityInstance SerializedPropagatedFrom
|
|
{
|
|
get { return this.propagatedFrom; }
|
|
set { this.propagatedFrom = value; }
|
|
}
|
|
|
|
[DataMember(Name = "originalExceptionSource")]
|
|
internal ActivityInstanceReference SerializedOriginalExceptionSource
|
|
{
|
|
get { return this.originalExceptionSource; }
|
|
set { this.originalExceptionSource = value; }
|
|
}
|
|
|
|
public override void TraceCompleted()
|
|
{
|
|
if (TD.CompleteFaultWorkItemIsEnabled())
|
|
{
|
|
TD.CompleteFaultWorkItem(this.ActivityInstance.Activity.GetType().ToString(), this.ActivityInstance.Activity.DisplayName, this.ActivityInstance.Id, this.originalExceptionSource.ActivityInstance.Activity.GetType().ToString(), this.originalExceptionSource.ActivityInstance.Activity.DisplayName, this.originalExceptionSource.ActivityInstance.Id, this.propagatedException);
|
|
}
|
|
}
|
|
|
|
public override void TraceScheduled()
|
|
{
|
|
if (TD.ScheduleFaultWorkItemIsEnabled())
|
|
{
|
|
TD.ScheduleFaultWorkItem(this.ActivityInstance.Activity.GetType().ToString(), this.ActivityInstance.Activity.DisplayName, this.ActivityInstance.Id, this.originalExceptionSource.ActivityInstance.Activity.GetType().ToString(), this.originalExceptionSource.ActivityInstance.Activity.DisplayName, this.originalExceptionSource.ActivityInstance.Id, this.propagatedException);
|
|
}
|
|
}
|
|
|
|
public override void TraceStarting()
|
|
{
|
|
if (TD.StartFaultWorkItemIsEnabled())
|
|
{
|
|
TD.StartFaultWorkItem(this.ActivityInstance.Activity.GetType().ToString(), this.ActivityInstance.Activity.DisplayName, this.ActivityInstance.Id, this.originalExceptionSource.ActivityInstance.Activity.GetType().ToString(), this.originalExceptionSource.ActivityInstance.Activity.DisplayName, this.originalExceptionSource.ActivityInstance.Id, this.propagatedException);
|
|
}
|
|
}
|
|
|
|
public override bool Execute(ActivityExecutor executor, BookmarkManager bookmarkManager)
|
|
{
|
|
NativeActivityFaultContext faultContext = null;
|
|
|
|
try
|
|
{
|
|
faultContext = new NativeActivityFaultContext(this.ActivityInstance, executor, bookmarkManager, this.propagatedException, this.originalExceptionSource);
|
|
this.callbackWrapper.Invoke(faultContext, this.propagatedException, this.propagatedFrom);
|
|
|
|
if (!faultContext.IsFaultHandled)
|
|
{
|
|
SetExceptionToPropagateWithoutAbort(this.propagatedException);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (Fx.IsFatal(e))
|
|
{
|
|
throw;
|
|
}
|
|
|
|
this.ExceptionToPropagate = e;
|
|
}
|
|
finally
|
|
{
|
|
if (faultContext != null)
|
|
{
|
|
faultContext.Dispose();
|
|
}
|
|
|
|
// Tell the executor to decrement its no persist count persistence of exceptions is disabled.
|
|
executor.ExitNoPersistForExceptionPropagation();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|