Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / RunTime / DebugEngine / DebugControllerThread.cs / 1305376 / DebugControllerThread.cs
#region Using directives
using System;
using System.Threading;
using System.Reflection;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Globalization;
using Microsoft.Win32;
#endregion
namespace System.Workflow.Runtime.DebugEngine
{
internal sealed class DebugControllerThread
{
#region Data members
private Thread controllerThread = null;
private int threadId = 0;
private ManualResetEvent threadInitializedEvent = null;
private volatile bool runThread = false;
private static readonly string ExpressionEvaluationFrameTypeName = "ExpressionEvaluationFrameTypeName";
#endregion
#region Methods
public DebugControllerThread()
{
this.threadInitializedEvent = new ManualResetEvent(false);
this.threadInitializedEvent.Reset();
this.controllerThread = new Thread(ControllerThreadFunction);
this.controllerThread.IsBackground = true;
this.controllerThread.Priority = ThreadPriority.Lowest;
this.controllerThread.Name = "__dct__";
}
public void RunThread(IInstanceTable instanceTable)
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.DebugControllerThread():"));
if (this.controllerThread == null)
return;
this.runThread = true;
this.controllerThread.Start(instanceTable);
this.threadInitializedEvent.WaitOne();
}
public void StopThread()
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.StopThread():"));
try
{
if (this.controllerThread != null)
{
this.runThread = false;
Thread.Sleep(10);
// On x64 we put the debug controller thread to Sleep(Timeout.Infinite) in
// ExpressionEvaluationFunction. This thread needs to be started before it
// a Join can execute.
if (this.controllerThread.IsAlive && IntPtr.Size == 8)
{
while (this.controllerThread.ThreadState == System.Threading.ThreadState.WaitSleepJoin)
{
this.controllerThread.Start();
this.controllerThread.Join();
}
}
else
this.controllerThread.Join();
}
}
catch (ThreadStateException)
{
// Ignore the ThreadStateException which will be thrown when StopThread() is called during
// AppDomain unload.
}
finally
{
this.controllerThread = null;
}
this.controllerThread = null;
this.threadId = 0;
this.threadInitializedEvent = null;
}
private void ControllerThreadFunction(object instanceTable)
{
try
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.ControllerThreadFunction():"));
IExpressionEvaluationFrame expressionEvaluationFrame = null;
try
{
RegistryKey debugEngineSubKey = Registry.LocalMachine.OpenSubKey(RegistryKeys.DebuggerSubKey);
if (debugEngineSubKey != null)
{
string evaluationFrameTypeName = debugEngineSubKey.GetValue(ExpressionEvaluationFrameTypeName, String.Empty) as string;
if (!String.IsNullOrEmpty(evaluationFrameTypeName) && Type.GetType(evaluationFrameTypeName) != null)
expressionEvaluationFrame = Activator.CreateInstance(Type.GetType(evaluationFrameTypeName)) as IExpressionEvaluationFrame;
}
}
catch { }
finally
{
if (expressionEvaluationFrame == null)
expressionEvaluationFrame = Activator.CreateInstance(Type.GetType("Microsoft.Workflow.DebugEngine.ExpressionEvaluationFrame, Microsoft.Workflow.ExpressionEvaluation, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")) as IExpressionEvaluationFrame;
}
Debug.Assert(expressionEvaluationFrame != null, "Failed to create Expression Evaluation Frame.");
if (expressionEvaluationFrame != null)
expressionEvaluationFrame.CreateEvaluationFrame((IInstanceTable)instanceTable, (DebugEngineCallback)Delegate.CreateDelegate(typeof(DebugEngineCallback), this, "ExpressionEvaluationFunction"));
}
catch
{
// Don't throw exceptions to the Runtime, it would terminate the debugee.
}
}
// This thread spins forever. It is used by the Debug Engine to perform expression evaluation as a "carrier
// wave". It is created only when the debugger is attached and terminates itself when the debugger isn't
// attached anymore.
public void ExpressionEvaluationFunction()
{
this.threadId = NativeMethods.GetCurrentThreadId();
this.threadInitializedEvent.Set();
using (new DebuggerThreadMarker())
{
// If an exception occurs somehow, continue to spin.
while (this.runThread)
{
try
{
// Expression eval on x64 does not work (bug 18143) so
// don't let the thread spin.
if (IntPtr.Size == 8)
{
Thread.Sleep(Timeout.Infinite);
}
else
// Spin within the try catch.
while (this.runThread) ;
}
catch (ThreadAbortException)
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.ExpressionEvaluationFunction(): ThreadAbortException"));
// Explicitly do not call ResetAbort().
throw;
}
catch
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.ExpressionEvaluationFunction(): other exception"));
}
}
}
}
#endregion
#region Properties
public int ThreadId
{
get
{
return this.threadId;
}
}
public int ManagedThreadId
{
get
{
return this.controllerThread.ManagedThreadId;
}
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
#region Using directives
using System;
using System.Threading;
using System.Reflection;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Globalization;
using Microsoft.Win32;
#endregion
namespace System.Workflow.Runtime.DebugEngine
{
internal sealed class DebugControllerThread
{
#region Data members
private Thread controllerThread = null;
private int threadId = 0;
private ManualResetEvent threadInitializedEvent = null;
private volatile bool runThread = false;
private static readonly string ExpressionEvaluationFrameTypeName = "ExpressionEvaluationFrameTypeName";
#endregion
#region Methods
public DebugControllerThread()
{
this.threadInitializedEvent = new ManualResetEvent(false);
this.threadInitializedEvent.Reset();
this.controllerThread = new Thread(ControllerThreadFunction);
this.controllerThread.IsBackground = true;
this.controllerThread.Priority = ThreadPriority.Lowest;
this.controllerThread.Name = "__dct__";
}
public void RunThread(IInstanceTable instanceTable)
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.DebugControllerThread():"));
if (this.controllerThread == null)
return;
this.runThread = true;
this.controllerThread.Start(instanceTable);
this.threadInitializedEvent.WaitOne();
}
public void StopThread()
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.StopThread():"));
try
{
if (this.controllerThread != null)
{
this.runThread = false;
Thread.Sleep(10);
// On x64 we put the debug controller thread to Sleep(Timeout.Infinite) in
// ExpressionEvaluationFunction. This thread needs to be started before it
// a Join can execute.
if (this.controllerThread.IsAlive && IntPtr.Size == 8)
{
while (this.controllerThread.ThreadState == System.Threading.ThreadState.WaitSleepJoin)
{
this.controllerThread.Start();
this.controllerThread.Join();
}
}
else
this.controllerThread.Join();
}
}
catch (ThreadStateException)
{
// Ignore the ThreadStateException which will be thrown when StopThread() is called during
// AppDomain unload.
}
finally
{
this.controllerThread = null;
}
this.controllerThread = null;
this.threadId = 0;
this.threadInitializedEvent = null;
}
private void ControllerThreadFunction(object instanceTable)
{
try
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.ControllerThreadFunction():"));
IExpressionEvaluationFrame expressionEvaluationFrame = null;
try
{
RegistryKey debugEngineSubKey = Registry.LocalMachine.OpenSubKey(RegistryKeys.DebuggerSubKey);
if (debugEngineSubKey != null)
{
string evaluationFrameTypeName = debugEngineSubKey.GetValue(ExpressionEvaluationFrameTypeName, String.Empty) as string;
if (!String.IsNullOrEmpty(evaluationFrameTypeName) && Type.GetType(evaluationFrameTypeName) != null)
expressionEvaluationFrame = Activator.CreateInstance(Type.GetType(evaluationFrameTypeName)) as IExpressionEvaluationFrame;
}
}
catch { }
finally
{
if (expressionEvaluationFrame == null)
expressionEvaluationFrame = Activator.CreateInstance(Type.GetType("Microsoft.Workflow.DebugEngine.ExpressionEvaluationFrame, Microsoft.Workflow.ExpressionEvaluation, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")) as IExpressionEvaluationFrame;
}
Debug.Assert(expressionEvaluationFrame != null, "Failed to create Expression Evaluation Frame.");
if (expressionEvaluationFrame != null)
expressionEvaluationFrame.CreateEvaluationFrame((IInstanceTable)instanceTable, (DebugEngineCallback)Delegate.CreateDelegate(typeof(DebugEngineCallback), this, "ExpressionEvaluationFunction"));
}
catch
{
// Don't throw exceptions to the Runtime, it would terminate the debugee.
}
}
// This thread spins forever. It is used by the Debug Engine to perform expression evaluation as a "carrier
// wave". It is created only when the debugger is attached and terminates itself when the debugger isn't
// attached anymore.
public void ExpressionEvaluationFunction()
{
this.threadId = NativeMethods.GetCurrentThreadId();
this.threadInitializedEvent.Set();
using (new DebuggerThreadMarker())
{
// If an exception occurs somehow, continue to spin.
while (this.runThread)
{
try
{
// Expression eval on x64 does not work (bug 18143) so
// don't let the thread spin.
if (IntPtr.Size == 8)
{
Thread.Sleep(Timeout.Infinite);
}
else
// Spin within the try catch.
while (this.runThread) ;
}
catch (ThreadAbortException)
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.ExpressionEvaluationFunction(): ThreadAbortException"));
// Explicitly do not call ResetAbort().
throw;
}
catch
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.ExpressionEvaluationFunction(): other exception"));
}
}
}
}
#endregion
#region Properties
public int ThreadId
{
get
{
return this.threadId;
}
}
public int ManagedThreadId
{
get
{
return this.controllerThread.ManagedThreadId;
}
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Registry.cs
- TrackingParameters.cs
- LocatorPartList.cs
- DataObjectEventArgs.cs
- RenderCapability.cs
- CustomUserNameSecurityTokenAuthenticator.cs
- DataSourceDescriptorCollection.cs
- IgnoreSectionHandler.cs
- WebPartDescriptionCollection.cs
- StateDesignerConnector.cs
- GraphicsState.cs
- WorkflowOwnershipException.cs
- TransformedBitmap.cs
- Animatable.cs
- FieldNameLookup.cs
- CacheSection.cs
- ScriptingProfileServiceSection.cs
- AuthorizationRule.cs
- SchemaImporterExtensionElement.cs
- RelationshipEnd.cs
- CustomErrorsSection.cs
- StateMachineAction.cs
- StyleCollection.cs
- Lazy.cs
- RectAnimation.cs
- FormViewDeleteEventArgs.cs
- _AcceptOverlappedAsyncResult.cs
- CLSCompliantAttribute.cs
- UIAgentRequest.cs
- ComplexBindingPropertiesAttribute.cs
- WindowsServiceCredential.cs
- DataGridViewLinkColumn.cs
- ScrollPatternIdentifiers.cs
- XmlUtil.cs
- MimeTypeAttribute.cs
- CmsUtils.cs
- JsonStringDataContract.cs
- RepeaterItemCollection.cs
- SafeFreeMibTable.cs
- sqlser.cs
- ObjectStateFormatter.cs
- UnsafeNativeMethods.cs
- XmlSchemaInfo.cs
- RoleGroupCollection.cs
- BitmapEffectDrawing.cs
- DataTableTypeConverter.cs
- SystemBrushes.cs
- ProfileModule.cs
- DaylightTime.cs
- LocalizableResourceBuilder.cs
- DebugView.cs
- GZipDecoder.cs
- ValuePattern.cs
- Polygon.cs
- ButtonAutomationPeer.cs
- MetadataUtilsSmi.cs
- SmtpSpecifiedPickupDirectoryElement.cs
- HtmlElementEventArgs.cs
- TimersDescriptionAttribute.cs
- CommandCollectionEditor.cs
- MultiDataTrigger.cs
- PrintPreviewControl.cs
- TdsParserSessionPool.cs
- DataReaderContainer.cs
- HashHelper.cs
- NumericUpDown.cs
- SettingsPropertyWrongTypeException.cs
- SqlUDTStorage.cs
- DataPagerFieldCollection.cs
- mda.cs
- AnonymousIdentificationSection.cs
- ParallelDesigner.cs
- SafeFileMappingHandle.cs
- TransactionFlowElement.cs
- TreeNodeEventArgs.cs
- FieldToken.cs
- QilBinary.cs
- TextMetrics.cs
- WindowsImpersonationContext.cs
- TaskCanceledException.cs
- RsaSecurityTokenAuthenticator.cs
- DataServiceContext.cs
- ConfigXmlElement.cs
- SqlPersonalizationProvider.cs
- ActivityExecutionContext.cs
- ToolStripMenuItem.cs
- QilStrConcatenator.cs
- RegionIterator.cs
- bidPrivateBase.cs
- Point3DValueSerializer.cs
- Pointer.cs
- EnvironmentPermission.cs
- VideoDrawing.cs
- CatalogZone.cs
- TransformValueSerializer.cs
- GeneratedView.cs
- ProfileSection.cs
- UnsignedPublishLicense.cs
- BorderGapMaskConverter.cs
- ContextMenuService.cs