1 //----------------------------------------------------------------------------- 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //----------------------------------------------------------------------------- 4 namespace System.ServiceModel.ComIntegration 5 { 6 using System; 7 using System.Diagnostics; 8 using System.Runtime; 9 using System.Runtime.InteropServices; 10 using System.ServiceModel.Diagnostics; 11 using System.Threading; 12 13 class ComPlusSynchronizationContext : SynchronizationContext 14 { 15 IServiceActivity activity; 16 bool postSynchronous; 17 ComPlusSynchronizationContext(IServiceActivity activity, bool postSynchronous)18 public ComPlusSynchronizationContext(IServiceActivity activity, 19 bool postSynchronous) 20 { 21 this.activity = activity; 22 this.postSynchronous = postSynchronous; 23 } 24 Send(SendOrPostCallback d, Object state)25 public override void Send(SendOrPostCallback d, Object state) 26 { 27 Fx.Assert("Send should never be called"); 28 } 29 Post(SendOrPostCallback d, Object state)30 public override void Post(SendOrPostCallback d, Object state) 31 { 32 ComPlusActivityTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationEnteringActivity, 33 SR.TraceCodeComIntegrationEnteringActivity); 34 35 ServiceCall call = new ServiceCall(d, state); 36 if (this.postSynchronous) 37 { 38 this.activity.SynchronousCall(call); 39 } 40 else 41 { 42 this.activity.AsynchronousCall(call); 43 } 44 ComPlusActivityTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationLeftActivity, 45 SR.TraceCodeComIntegrationLeftActivity); 46 } 47 Dispose()48 public void Dispose() 49 { 50 while (Marshal.ReleaseComObject(this.activity) > 0); 51 } 52 53 class ServiceCall : IServiceCall 54 { 55 SendOrPostCallback callback; 56 Object state; 57 ServiceCall(SendOrPostCallback callback, Object state)58 public ServiceCall(SendOrPostCallback callback, 59 Object state) 60 { 61 this.callback = callback; 62 this.state = state; 63 } 64 65 66 OnCall()67 public void OnCall() 68 { 69 ServiceModelActivity activity = null; 70 try 71 { 72 Guid guidLogicalThreadID = Guid.Empty; 73 74 if (DiagnosticUtility.ShouldUseActivity) 75 { 76 IComThreadingInfo comThreadingInfo; 77 comThreadingInfo = (IComThreadingInfo)SafeNativeMethods.CoGetObjectContext(ComPlusActivityTrace.IID_IComThreadingInfo); 78 79 if (comThreadingInfo != null) 80 { 81 82 comThreadingInfo.GetCurrentLogicalThreadId(out guidLogicalThreadID); 83 84 activity = ServiceModelActivity.CreateBoundedActivity(guidLogicalThreadID); 85 } 86 ServiceModelActivity.Start(activity, SR.GetString(SR.TransferringToComplus, guidLogicalThreadID.ToString()), ActivityType.TransferToComPlus); 87 } 88 ComPlusActivityTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationExecutingCall, SR.TraceCodeComIntegrationExecutingCall); 89 90 this.callback(this.state); 91 } 92 catch (Exception e) 93 { 94 if (Fx.IsFatal(e)) 95 throw; 96 97 DiagnosticUtility.InvokeFinalHandler(e); 98 } 99 finally 100 { 101 if (activity != null) 102 { 103 activity.Dispose(); 104 activity = null; 105 } 106 } 107 } 108 } 109 } 110 } 111