Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / UIAutomation / UIAutomationClient / MS / Internal / Automation / QueueProcessor.cs / 1305600 / 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
- SingleConverter.cs
- TableRowCollection.cs
- WindowInteractionStateTracker.cs
- DataGridViewHeaderCell.cs
- TypeDescriptionProviderAttribute.cs
- Subtree.cs
- WindowsScroll.cs
- KeyNotFoundException.cs
- DebugHandleTracker.cs
- DeclaredTypeValidator.cs
- FillBehavior.cs
- SurrogateSelector.cs
- RtType.cs
- BadImageFormatException.cs
- IdentifierCollection.cs
- WrapPanel.cs
- RenderData.cs
- XXXOnTypeBuilderInstantiation.cs
- FixedTextBuilder.cs
- FormViewDeleteEventArgs.cs
- DBSqlParser.cs
- TaskFormBase.cs
- ActivityFunc.cs
- TextEndOfParagraph.cs
- XmlAnyAttributeAttribute.cs
- WebBrowserNavigatedEventHandler.cs
- ToolStripSplitStackLayout.cs
- RequestQueue.cs
- BatchWriter.cs
- XmlSchemaNotation.cs
- ParentUndoUnit.cs
- SQLConvert.cs
- shaperfactory.cs
- EntityFrameworkVersions.cs
- EmbeddedMailObject.cs
- QuaternionAnimation.cs
- MaterialCollection.cs
- BigIntegerStorage.cs
- EncodingInfo.cs
- SelectionWordBreaker.cs
- NotifyInputEventArgs.cs
- Win32PrintDialog.cs
- ReferencedCollectionType.cs
- GroupBox.cs
- MatrixAnimationUsingKeyFrames.cs
- Positioning.cs
- WebPartConnectionsDisconnectVerb.cs
- XmlReflectionMember.cs
- DisplayNameAttribute.cs
- UICuesEvent.cs
- UInt64.cs
- SHA1CryptoServiceProvider.cs
- GraphicsState.cs
- ReadOnlyTernaryTree.cs
- NavigateEvent.cs
- PermissionToken.cs
- WebConfigurationHost.cs
- EventLogPermission.cs
- HashCodeCombiner.cs
- ISessionStateStore.cs
- SamlEvidence.cs
- Function.cs
- RelationshipType.cs
- RemotingConfigParser.cs
- EmptyCollection.cs
- SimplePropertyEntry.cs
- ModifierKeysConverter.cs
- SQLDecimal.cs
- SerializationAttributes.cs
- StorageFunctionMapping.cs
- UniqueIdentifierService.cs
- LinqDataSourceSelectEventArgs.cs
- WaitForChangedResult.cs
- DataGridViewSelectedColumnCollection.cs
- AsyncPostBackErrorEventArgs.cs
- GridSplitterAutomationPeer.cs
- DeclarativeCatalogPart.cs
- OrderedHashRepartitionEnumerator.cs
- basevalidator.cs
- XmlUtil.cs
- MobileControlDesigner.cs
- FilePrompt.cs
- TimeoutHelper.cs
- BulletChrome.cs
- SecurityUtils.cs
- TabPage.cs
- TransactionChannel.cs
- DataViewListener.cs
- XXXInfos.cs
- PathTooLongException.cs
- CalculatedColumn.cs
- MessageQueueEnumerator.cs
- XmlSchemaComplexType.cs
- SeekStoryboard.cs
- SQLChars.cs
- EditorReuseAttribute.cs
- ReflectionServiceProvider.cs
- TraceUtils.cs
- FormViewActionList.cs
- DataPointer.cs