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
- SecurityDocument.cs
- ValueTypeFieldReference.cs
- Object.cs
- ObjectParameter.cs
- AxParameterData.cs
- FormViewCommandEventArgs.cs
- WriterOutput.cs
- PageAsyncTask.cs
- CustomWebEventKey.cs
- ByteAnimation.cs
- PathStreamGeometryContext.cs
- KeyConstraint.cs
- CommandPlan.cs
- DrawToolTipEventArgs.cs
- ColorConvertedBitmapExtension.cs
- RegexCapture.cs
- ForEachDesigner.xaml.cs
- GenerateScriptTypeAttribute.cs
- CompiledRegexRunnerFactory.cs
- AsmxEndpointPickerExtension.cs
- BackgroundWorker.cs
- XXXInfos.cs
- TextTreeText.cs
- TextSpan.cs
- OperatingSystem.cs
- PasswordBoxAutomationPeer.cs
- SqlDataReaderSmi.cs
- SoapCodeExporter.cs
- RelatedImageListAttribute.cs
- ElementAtQueryOperator.cs
- Knowncolors.cs
- CommandSet.cs
- PhysicalFontFamily.cs
- WebZoneDesigner.cs
- DataBindingsDialog.cs
- ParameterRetriever.cs
- CapabilitiesUse.cs
- Events.cs
- HttpResponse.cs
- ErrorTableItemStyle.cs
- XmlConvert.cs
- WindowsFont.cs
- ExpandoObject.cs
- ListControlConvertEventArgs.cs
- WasNotInstalledException.cs
- UrlMappingCollection.cs
- Section.cs
- Sequence.cs
- SafeWaitHandle.cs
- EventToken.cs
- EUCJPEncoding.cs
- TemplateNameScope.cs
- TemplateControl.cs
- XmlSchemaAnyAttribute.cs
- ButtonField.cs
- ProviderSettings.cs
- DataServiceHost.cs
- ActiveXSite.cs
- ActivityTypeResolver.xaml.cs
- AppDomainGrammarProxy.cs
- KeyNotFoundException.cs
- GifBitmapDecoder.cs
- FlowDocument.cs
- FreezableCollection.cs
- TypeSystem.cs
- SourceFileBuildProvider.cs
- MasterPageCodeDomTreeGenerator.cs
- Funcletizer.cs
- PrincipalPermission.cs
- WebPartMenu.cs
- QueryResponse.cs
- SoapSchemaMember.cs
- ToolTip.cs
- TdsParserSafeHandles.cs
- MenuItemStyleCollectionEditor.cs
- UpdateException.cs
- DataGridViewRowPostPaintEventArgs.cs
- DesignTimeParseData.cs
- IntegerFacetDescriptionElement.cs
- SafeEventLogReadHandle.cs
- BinaryMethodMessage.cs
- TextModifierScope.cs
- ISessionStateStore.cs
- DataServiceEntityAttribute.cs
- base64Transforms.cs
- XmlRawWriterWrapper.cs
- XomlCompilerParameters.cs
- Listbox.cs
- TableCellAutomationPeer.cs
- ExeConfigurationFileMap.cs
- LineInfo.cs
- MultiTargetingUtil.cs
- ProfileInfo.cs
- PipelineModuleStepContainer.cs
- OperationResponse.cs
- UInt32Converter.cs
- WindowClosedEventArgs.cs
- StreamGeometryContext.cs
- DeferredTextReference.cs
- MatrixAnimationUsingPath.cs