|
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.ComIntegration
{
using System;
using System.Diagnostics;
using System.Runtime;
using System.Runtime.InteropServices;
using System.ServiceModel.Diagnostics;
using System.Threading;
class ComPlusSynchronizationContext : SynchronizationContext
{
IServiceActivity activity;
bool postSynchronous;
public ComPlusSynchronizationContext(IServiceActivity activity,
bool postSynchronous)
{
this.activity = activity;
this.postSynchronous = postSynchronous;
}
public override void Send(SendOrPostCallback d, Object state)
{
Fx.Assert("Send should never be called");
}
public override void Post(SendOrPostCallback d, Object state)
{
ComPlusActivityTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationEnteringActivity,
SR.TraceCodeComIntegrationEnteringActivity);
ServiceCall call = new ServiceCall(d, state);
if (this.postSynchronous)
{
this.activity.SynchronousCall(call);
}
else
{
this.activity.AsynchronousCall(call);
}
ComPlusActivityTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationLeftActivity,
SR.TraceCodeComIntegrationLeftActivity);
}
public void Dispose()
{
while (Marshal.ReleaseComObject(this.activity) > 0);
}
class ServiceCall : IServiceCall
{
SendOrPostCallback callback;
Object state;
public ServiceCall(SendOrPostCallback callback,
Object state)
{
this.callback = callback;
this.state = state;
}
public void OnCall()
{
ServiceModelActivity activity = null;
try
{
Guid guidLogicalThreadID = Guid.Empty;
if (DiagnosticUtility.ShouldUseActivity)
{
IComThreadingInfo comThreadingInfo;
comThreadingInfo = (IComThreadingInfo)SafeNativeMethods.CoGetObjectContext(ComPlusActivityTrace.IID_IComThreadingInfo);
if (comThreadingInfo != null)
{
comThreadingInfo.GetCurrentLogicalThreadId(out guidLogicalThreadID);
activity = ServiceModelActivity.CreateBoundedActivity(guidLogicalThreadID);
}
ServiceModelActivity.Start(activity, SR.GetString(SR.TransferringToComplus, guidLogicalThreadID.ToString()), ActivityType.TransferToComPlus);
}
ComPlusActivityTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationExecutingCall, SR.TraceCodeComIntegrationExecutingCall);
this.callback(this.state);
}
catch (Exception e)
{
if (Fx.IsFatal(e))
throw;
DiagnosticUtility.InvokeFinalHandler(e);
}
finally
{
if (activity != null)
{
activity.Dispose();
activity = null;
}
}
}
}
}
}
|