Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / UIAutomation / UIAutomationClient / MS / Internal / Automation / QueueProcessor.cs / 1 / QueueProcessor.cs
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
//
// Description: Class to create a queue on its own thread.
//
// History:
// 06/17/2003 : BrendanM Ported to WCP
//
//---------------------------------------------------------------------------
// PRESHARP: In order to avoid generating warnings about unkown message numbers and unknown pragmas.
#pragma warning disable 1634, 1691
using System.Windows.Automation;
using System.Windows.Automation.Provider;
using System;
using System.Threading;
using System.Collections;
using System.Diagnostics;
using MS.Internal.Automation;
using MS.Win32;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
namespace MS.Internal.Automation
{
// Abstract class for worker objects queued to the QueueProcessor class
internal abstract class QueueItem
{
internal abstract void Process();
}
// Class to create a queue on its own thread. Used on the PAW client-side
// to queue client callbacks. This prevents a deadlock situation when the
// client calls back into PAW from w/in a callback. All events are queued
// through this class.
internal class QueueProcessor
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
// Usage is create QueueProcessor object and call StartOnThread
internal QueueProcessor(int initCapacity)
{
_ev = new AutoResetEvent(false);
_q = Queue.Synchronized(new Queue(initCapacity));
}
internal QueueProcessor()
: this(4)
{
}
#endregion Constructors
//------------------------------------------------------
//
// Internal Methods
//
//-----------------------------------------------------
#region Internal Methods
internal void StartOnThread()
{
_quitting = false;
// create and start a background thread for this worker window to run on
// (background threads will exit if the main and foreground threads exit)
ThreadStart threadStart = new ThreadStart(WaitForWork);
_thread = new Thread(threadStart);
_thread.IsBackground = true;
_thread.Start();
}
// Post a work item to the queue (from another thread)
internal bool PostWorkItem(QueueItem workItem)
{
Debug.Assert(!_quitting, "Can't add items to queue when quitting");
_q.Enqueue(workItem);
_ev.Set();
return true;
}
// Post a work item and wait for it to be processed
// Return true if the item was processed w/in 2 sec else false
internal bool PostSyncWorkItem(QueueItem workItem)
{
Debug.Assert(!_quitting, "Can't add items to queue when quitting");
SyncQueueItem syncItem = new SyncQueueItem(workItem);
_q.Enqueue(syncItem);
_ev.Set();
return syncItem._ev.WaitOne(2000, false);
}
// Stop queuing and clean up (from another thread)
internal void PostQuit()
{
_quitting = true;
_ev.Set();
}
#endregion Internal Methods
//------------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
// The loop the thread uses to wait for queue items to process
private void WaitForWork()
{
SafeWaitHandle handle = _ev.SafeWaitHandle;
UnsafeNativeMethods.MSG msg = new UnsafeNativeMethods.MSG();
while (!_quitting)
{
// pump any messages
while (UnsafeNativeMethods.PeekMessage(ref msg, NativeMethods.HWND.NULL, 0, 0, UnsafeNativeMethods.PM_REMOVE))
{
if (msg.message == UnsafeNativeMethods.WM_QUIT)
{
break;
}
// From the Windows SDK documentation:
// The return value specifies the value returned by the window procedure.
// Although its meaning depends on the message being dispatched, the return
// value generally is ignored.
#pragma warning suppress 6031, 6523
UnsafeNativeMethods.DispatchMessage(ref msg);
}
// do any work items in the queue
DrainQueue();
int lastWin32Error = 0;
int result = Misc.TryMsgWaitForMultipleObjects(handle, false, UnsafeNativeMethods.INFINITE, UnsafeNativeMethods.QS_ALLINPUT, ref lastWin32Error);
if (result == UnsafeNativeMethods.WAIT_FAILED || result == UnsafeNativeMethods.WAIT_TIMEOUT)
{
DrainQueue();
Debug.Assert(_quitting, "MsgWaitForMultipleObjects failed while WaitForWork");
break;
}
}
DrainQueue();
}
private void DrainQueue()
{
// It's possible items could be enqueued between when we check for the count
// and dequeue but the event is set then and we'll come back into DrainQueue.
// (note: don't use a for loop here because as the counter is incremented
// Count is decremented and we'll only process half the queue)
while (_q.Count > 0)
{
// pull an item off the queue, process, then clear it
QueueItem item = (QueueItem)_q.Dequeue();
if (! _quitting)
{
try
{
item.Process();
}
catch (Exception e)
{
if (Misc.IsCriticalException(e))
throw;
// Eat it.
// There's no place to let this exception percolate out
// to so we'll stop it here.
}
}
}
}
#endregion Private Methods
//-----------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------
#region Private Fields
Thread _thread; // the thread on which QueueItem's are processed
private Queue _q; // a synchronized queue
private AutoResetEvent _ev; // notifies when new queue items show up
private bool _quitting; // true if need to stop queueing
#endregion Private Fields
}
// Class is used only by QueueProcessor class itself - wraps
// another QueueItem, and fires an event when it is complete.
internal class SyncQueueItem : QueueItem
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
internal SyncQueueItem(QueueItem qItem)
{
_ev = new AutoResetEvent(false);
_qItem = qItem;
}
#endregion Constructors
//-----------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------
#region Internal Methods
internal override void Process()
{
_qItem.Process();
_ev.Set();
}
#endregion Internal Methods
//-----------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------
#region Private Fields
// Not many of these will be created at a time so having the
// event in the class is OK and easier than having just one
// that manages any [....] method call.
internal AutoResetEvent _ev;
private QueueItem _qItem;
#endregion Private Fields
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
//
// Description: Class to create a queue on its own thread.
//
// History:
// 06/17/2003 : BrendanM Ported to WCP
//
//---------------------------------------------------------------------------
// PRESHARP: In order to avoid generating warnings about unkown message numbers and unknown pragmas.
#pragma warning disable 1634, 1691
using System.Windows.Automation;
using System.Windows.Automation.Provider;
using System;
using System.Threading;
using System.Collections;
using System.Diagnostics;
using MS.Internal.Automation;
using MS.Win32;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
namespace MS.Internal.Automation
{
// Abstract class for worker objects queued to the QueueProcessor class
internal abstract class QueueItem
{
internal abstract void Process();
}
// Class to create a queue on its own thread. Used on the PAW client-side
// to queue client callbacks. This prevents a deadlock situation when the
// client calls back into PAW from w/in a callback. All events are queued
// through this class.
internal class QueueProcessor
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
// Usage is create QueueProcessor object and call StartOnThread
internal QueueProcessor(int initCapacity)
{
_ev = new AutoResetEvent(false);
_q = Queue.Synchronized(new Queue(initCapacity));
}
internal QueueProcessor()
: this(4)
{
}
#endregion Constructors
//------------------------------------------------------
//
// Internal Methods
//
//-----------------------------------------------------
#region Internal Methods
internal void StartOnThread()
{
_quitting = false;
// create and start a background thread for this worker window to run on
// (background threads will exit if the main and foreground threads exit)
ThreadStart threadStart = new ThreadStart(WaitForWork);
_thread = new Thread(threadStart);
_thread.IsBackground = true;
_thread.Start();
}
// Post a work item to the queue (from another thread)
internal bool PostWorkItem(QueueItem workItem)
{
Debug.Assert(!_quitting, "Can't add items to queue when quitting");
_q.Enqueue(workItem);
_ev.Set();
return true;
}
// Post a work item and wait for it to be processed
// Return true if the item was processed w/in 2 sec else false
internal bool PostSyncWorkItem(QueueItem workItem)
{
Debug.Assert(!_quitting, "Can't add items to queue when quitting");
SyncQueueItem syncItem = new SyncQueueItem(workItem);
_q.Enqueue(syncItem);
_ev.Set();
return syncItem._ev.WaitOne(2000, false);
}
// Stop queuing and clean up (from another thread)
internal void PostQuit()
{
_quitting = true;
_ev.Set();
}
#endregion Internal Methods
//------------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
// The loop the thread uses to wait for queue items to process
private void WaitForWork()
{
SafeWaitHandle handle = _ev.SafeWaitHandle;
UnsafeNativeMethods.MSG msg = new UnsafeNativeMethods.MSG();
while (!_quitting)
{
// pump any messages
while (UnsafeNativeMethods.PeekMessage(ref msg, NativeMethods.HWND.NULL, 0, 0, UnsafeNativeMethods.PM_REMOVE))
{
if (msg.message == UnsafeNativeMethods.WM_QUIT)
{
break;
}
// From the Windows SDK documentation:
// The return value specifies the value returned by the window procedure.
// Although its meaning depends on the message being dispatched, the return
// value generally is ignored.
#pragma warning suppress 6031, 6523
UnsafeNativeMethods.DispatchMessage(ref msg);
}
// do any work items in the queue
DrainQueue();
int lastWin32Error = 0;
int result = Misc.TryMsgWaitForMultipleObjects(handle, false, UnsafeNativeMethods.INFINITE, UnsafeNativeMethods.QS_ALLINPUT, ref lastWin32Error);
if (result == UnsafeNativeMethods.WAIT_FAILED || result == UnsafeNativeMethods.WAIT_TIMEOUT)
{
DrainQueue();
Debug.Assert(_quitting, "MsgWaitForMultipleObjects failed while WaitForWork");
break;
}
}
DrainQueue();
}
private void DrainQueue()
{
// It's possible items could be enqueued between when we check for the count
// and dequeue but the event is set then and we'll come back into DrainQueue.
// (note: don't use a for loop here because as the counter is incremented
// Count is decremented and we'll only process half the queue)
while (_q.Count > 0)
{
// pull an item off the queue, process, then clear it
QueueItem item = (QueueItem)_q.Dequeue();
if (! _quitting)
{
try
{
item.Process();
}
catch (Exception e)
{
if (Misc.IsCriticalException(e))
throw;
// Eat it.
// There's no place to let this exception percolate out
// to so we'll stop it here.
}
}
}
}
#endregion Private Methods
//-----------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------
#region Private Fields
Thread _thread; // the thread on which QueueItem's are processed
private Queue _q; // a synchronized queue
private AutoResetEvent _ev; // notifies when new queue items show up
private bool _quitting; // true if need to stop queueing
#endregion Private Fields
}
// Class is used only by QueueProcessor class itself - wraps
// another QueueItem, and fires an event when it is complete.
internal class SyncQueueItem : QueueItem
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
internal SyncQueueItem(QueueItem qItem)
{
_ev = new AutoResetEvent(false);
_qItem = qItem;
}
#endregion Constructors
//-----------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------
#region Internal Methods
internal override void Process()
{
_qItem.Process();
_ev.Set();
}
#endregion Internal Methods
//-----------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------
#region Private Fields
// Not many of these will be created at a time so having the
// event in the class is OK and easier than having just one
// that manages any [....] method call.
internal AutoResetEvent _ev;
private QueueItem _qItem;
#endregion Private Fields
}
}
// 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
- _NetRes.cs
- ListSortDescriptionCollection.cs
- SqlXml.cs
- PagePropertiesChangingEventArgs.cs
- ToolStripPanel.cs
- StrokeNodeData.cs
- PtsPage.cs
- TextFormatterHost.cs
- WebPartAddingEventArgs.cs
- OleDbConnectionInternal.cs
- Base64Stream.cs
- ServiceOperationParameter.cs
- EntityDesignerBuildProvider.cs
- FaultCallbackWrapper.cs
- UnaryExpression.cs
- Image.cs
- ResizeGrip.cs
- ListBindingHelper.cs
- _Events.cs
- DataGridViewColumnStateChangedEventArgs.cs
- BinaryMethodMessage.cs
- Pen.cs
- TemplateBindingExtensionConverter.cs
- DynamicMetaObjectBinder.cs
- PassportAuthenticationEventArgs.cs
- GeneralTransform2DTo3D.cs
- HttpListenerElement.cs
- WebPartActionVerb.cs
- IUnknownConstantAttribute.cs
- DataObjectCopyingEventArgs.cs
- PropertyDescriptorCollection.cs
- CheckBoxStandardAdapter.cs
- CRYPTPROTECT_PROMPTSTRUCT.cs
- PictureBox.cs
- SoapAttributes.cs
- FindProgressChangedEventArgs.cs
- XmlParserContext.cs
- SchemaMerger.cs
- PasswordRecovery.cs
- PowerModeChangedEventArgs.cs
- AutoResizedEvent.cs
- CdpEqualityComparer.cs
- DependencyObjectType.cs
- CodeIdentifiers.cs
- ScalarConstant.cs
- TextServicesLoader.cs
- ManagementEventArgs.cs
- EventLogger.cs
- LineMetrics.cs
- ConnectionPoolManager.cs
- ControlAdapter.cs
- SchemaNames.cs
- ClientOptions.cs
- LostFocusEventManager.cs
- ProbeDuplexCD1AsyncResult.cs
- HTTPNotFoundHandler.cs
- AsyncInvokeContext.cs
- CodeStatement.cs
- StylusPointPropertyId.cs
- NativeMethods.cs
- CacheMode.cs
- DeploymentSection.cs
- ListViewSortEventArgs.cs
- ColorAnimationUsingKeyFrames.cs
- VariableQuery.cs
- WebPartEditVerb.cs
- DateTimeParse.cs
- Typeface.cs
- RuleSetDialog.Designer.cs
- InvokeWebServiceDesigner.cs
- ToolStripDropDownButton.cs
- VectorKeyFrameCollection.cs
- SelectionPatternIdentifiers.cs
- SectionXmlInfo.cs
- HealthMonitoringSection.cs
- MissingSatelliteAssemblyException.cs
- DataGridViewCellStyleEditor.cs
- UTF32Encoding.cs
- SapiInterop.cs
- GridEntryCollection.cs
- DataObjectPastingEventArgs.cs
- AsyncOperation.cs
- DataRelationPropertyDescriptor.cs
- AppDomainShutdownMonitor.cs
- ActivityTypeDesigner.xaml.cs
- OutputCacheSettings.cs
- XmlILAnnotation.cs
- DecimalConverter.cs
- AssemblyBuilderData.cs
- AlphabeticalEnumConverter.cs
- UIAgentAsyncBeginRequest.cs
- CapabilitiesAssignment.cs
- TagPrefixInfo.cs
- Claim.cs
- SurrogateDataContract.cs
- X509AsymmetricSecurityKey.cs
- GuidelineSet.cs
- TimeoutValidationAttribute.cs
- PersonalizationStateQuery.cs
- SmtpNtlmAuthenticationModule.cs