1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
//-----------------------------------------------------------------------------
// 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;
}
}
}
}
|