Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Threading / CountdownEvent.cs / 1305376 / CountdownEvent.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // // CountdownEvent.cs // //[....] // // A simple coordination data structure that we use for fork/join style parallelism. // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System; using System.Diagnostics; using System.Security.Permissions; using System.Runtime.InteropServices; using System.Threading; using System.Diagnostics.Contracts; namespace System.Threading { ////// Represents a synchronization primitive that is signaled when its count reaches zero. /// ////// All public and protected members of [ComVisible(false)] [DebuggerDisplay("Initial Count={InitialCount}, Current Count={CurrentCount}")] [HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)] public class CountdownEvent : IDisposable { // CountdownEvent is a simple synchronization primitive used for fork/join parallelism. We create a // latch with a count of N; threads then signal the latch, which decrements N by 1; other threads can // wait on the latch at any point; when the latch count reaches 0, all threads are woken and // subsequent waiters return without waiting. The implementation internally lazily creates a true // Win32 event as needed. We also use some amount of spinning on MP machines before falling back to a // wait. private int m_initialCount; // The original # of signals the latch was instantiated with. private volatile int m_currentCount; // The # of outstanding signals before the latch transitions to a signaled state. private ManualResetEventSlim m_event; // An event used to manage blocking and signaling. private volatile bool m_disposed; // Whether the latch has been disposed. ///are thread-safe and may be used /// concurrently from multiple threads, with the exception of Dispose, which /// must only be used when all other operations on the have /// completed, and Reset, which should only be used when no other threads are /// accessing the event. /// /// Initializes a new instance of /// The number of signals required to set theclass with the /// specified count. /// . /// public CountdownEvent(int initialCount) { if (initialCount < 0) { throw new ArgumentOutOfRangeException("initialCount"); } m_initialCount = initialCount; m_currentCount = initialCount; // Allocate a thin event, which internally defers creation of an actual Win32 event. m_event = new ManualResetEventSlim(); // If the latch was created with a count of 0, then it's already in the signaled state. if (initialCount == 0) { m_event.Set(); } } /// is less /// than 0. /// Gets the number of remaining signals required to set the event. /// ////// The number of remaining signals required to set the event. /// public int CurrentCount { get { return m_currentCount; } } ////// Gets the numbers of signals initially required to set the event. /// ////// The number of signals initially required to set the event. /// public int InitialCount { get { return m_initialCount; } } ////// Determines whether the event is set. /// ///true if the event is set; otherwise, false. public bool IsSet { get { // The latch is "completed" if its current count has reached 0. Note that this is NOT // the same thing is checking the event's IsCompleted property. There is a tiny window // of time, after the final decrement of the current count to 0 and before setting the // event, where the two values are out of [....]. return (m_currentCount == 0); } } ////// Gets a ///that is used to wait for the event to be set. /// A ///that is used to wait for the event to be set. The current instance has already been disposed. ////// public WaitHandle WaitHandle { get { ThrowIfDisposed(); return m_event.WaitHandle; } } ///should only be used if it's needed for integration with code bases /// that rely on having a WaitHandle. If all that's needed is to wait for the /// to be set, the method should be preferred. /// /// Releases all resources used by the current instance of ///. /// /// Unlike most of the members of public void Dispose() { // Gets rid of this latch's associated resources. This can consist of a Win32 event // which is (lazily) allocated by the underlying thin event. This method is not safe to // call concurrently -- i.e. a caller must coordinate to ensure only one thread is using // the latch at the time of the call to Dispose. Dispose(true); GC.SuppressFinalize(this); } ///, is not /// thread-safe and may not be used concurrently with other members of this instance. /// /// When overridden in a derived class, releases the unmanaged resources used by the /// /// true to release both managed and unmanaged resources; false to release /// only unmanaged resources. ///, and optionally releases the managed resources. /// /// Unlike most of the members of protected virtual void Dispose(bool disposing) { if (disposing) { m_event.Dispose(); m_disposed = true; } } ///, is not /// thread-safe and may not be used concurrently with other members of this instance. /// /// Registers a signal with the ///, decrementing its /// count. /// true if the signal caused the count to reach zero and the event was set; otherwise, /// false. ///The current instance is already set. /// ///The current instance has already been /// disposed. public bool Signal() { return Signal(1); } ////// Registers multiple signals with the /// The number of signals to register. ///, /// decrementing its count by the specified amount. /// true if the signals caused the count to reach zero and the event was set; otherwise, /// false. ////// The current instance is already set. -or- Or ///is greater than . /// /// is less /// than 1. The current instance has already been /// disposed. public bool Signal(int signalCount) { if (signalCount <= 0) { throw new ArgumentOutOfRangeException("signalCount"); } ThrowIfDisposed(); Contract.Assert(m_event != null); int observedCount; SpinWait spin = new SpinWait(); while (true) { observedCount = m_currentCount; // If the latch is already signaled, we will fail. if (observedCount < signalCount) { throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Decrement_BelowZero")); } // This disables the "CS0420: a reference to a volatile field will not be treated as volatile" warning // for this statement. This warning is clearly senseless for Interlocked operations. #pragma warning disable 0420 if (Interlocked.CompareExchange(ref m_currentCount, observedCount - signalCount, observedCount) == observedCount) #pragma warning restore 0420 { break; } // The CAS failed. Spin briefly and try again. spin.SpinOnce(); } // If we were the last to signal, set the event. if (observedCount == signalCount) { m_event.Set(); return true; } Contract.Assert(m_currentCount >= 0, "latch was decremented below zero"); return false; } ////// Increments the ///'s current count by one. /// The current instance is already /// set. ////// is equal to . /// The current instance has already been disposed. /// public void AddCount() { AddCount(1); } ////// Attempts to increment the ///'s current count by one. /// true if the increment succeeded; otherwise, false. If ///is /// already at zero. this will return false. /// is equal to . The current instance has already been /// disposed. public bool TryAddCount() { return TryAddCount(1); } ////// Increments the /// The value by which to increase's current count by a specified /// value. /// . /// /// is less than /// 0. The current instance is already /// set. ////// is equal to . The current instance has already been /// disposed. public void AddCount(int signalCount) { if (!TryAddCount(signalCount)) { throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Increment_AlreadyZero")); } } ////// Attempts to increment the /// The value by which to increase's current count by a /// specified value. /// . /// true if the increment succeeded; otherwise, false. If ///is /// already at zero this will return false. /// is less /// than 0. The current instance is already /// set. ////// is equal to . The current instance has already been /// disposed. public bool TryAddCount(int signalCount) { if (signalCount <= 0) { throw new ArgumentOutOfRangeException("signalCount"); } ThrowIfDisposed(); // Loop around until we successfully increment the count. int observedCount; SpinWait spin = new SpinWait(); while (true) { observedCount = m_currentCount; if (observedCount == 0) { return false; } else if (observedCount > (Int32.MaxValue - signalCount)) { throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Increment_AlreadyMax")); } // This disables the "CS0420: a reference to a volatile field will not be treated as volatile" warning // for this statement. This warning is clearly senseless for Interlocked operations. #pragma warning disable 0420 if (Interlocked.CompareExchange(ref m_currentCount, observedCount + signalCount, observedCount) == observedCount) #pragma warning restore 0420 { break; } // The CAS failed. Spin briefly and try again. spin.SpinOnce(); } return true; } ////// Resets the ///to the value of . /// /// Unlike most of the members of ///, Reset is not /// thread-safe and may not be used concurrently with other members of this instance. /// The current instance has already been /// disposed.. public void Reset() { Reset(m_initialCount); } ////// Resets the /// The number of signals required to set theto a specified value. /// . /// /// Unlike most of the members of ///, Reset is not /// thread-safe and may not be used concurrently with other members of this instance. /// /// is /// less than 0. The current instance has alread been disposed. public void Reset(int count) { ThrowIfDisposed(); if (count < 0) { throw new ArgumentOutOfRangeException("count"); } m_currentCount = count; m_initialCount = count; if (count == 0) { m_event.Set(); } else { m_event.Reset(); } } ////// Blocks the current thread until the ///is set. /// /// The caller of this method blocks indefinitely until the current instance is set. The caller will /// return immediately if the event is currently in a set state. /// ///The current instance has already been /// disposed. public void Wait() { Wait(Timeout.Infinite, new CancellationToken()); } ////// Blocks the current thread until the /// Theis set, while /// observing a . /// to /// observe. /// /// The caller of this method blocks indefinitely until the current instance is set. The caller will /// return immediately if the event is currently in a set state. If the /// ///CancellationToken being observed /// is canceled during the wait operation, an/// will be thrown. /// /// has been /// canceled. The current instance has already been /// disposed. public void Wait(CancellationToken cancellationToken) { Wait(Timeout.Infinite, cancellationToken); } ////// Blocks the current thread until the /// Ais set, using a /// to measure the time interval. /// that represents the number of /// milliseconds to wait, or a that represents -1 milliseconds to /// wait indefinitely. /// true if the ///was set; otherwise, /// false. /// is a negative /// number other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater /// than . The current instance has already been /// disposed. public bool Wait(TimeSpan timeout) { long totalMilliseconds = (long)timeout.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { throw new ArgumentOutOfRangeException("timeout"); } return Wait((int)totalMilliseconds, new CancellationToken()); } ////// Blocks the current thread until the /// Ais set, using /// a to measure the time interval, while observing a /// . /// that represents the number of /// milliseconds to wait, or a that represents -1 milliseconds to /// wait indefinitely. /// The to /// observe. /// true if the ///was set; otherwise, /// false. /// is a negative /// number other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater /// than . The current instance has already been /// disposed. ///public bool Wait(TimeSpan timeout, CancellationToken cancellationToken) { long totalMilliseconds = (long)timeout.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { throw new ArgumentOutOfRangeException("timeout"); } return Wait((int)totalMilliseconds, cancellationToken); } /// has /// been canceled. /// Blocks the current thread until the /// The number of milliseconds to wait, oris set, using a /// 32-bit signed integer to measure the time interval. /// (-1) to wait indefinitely. /// true if the ///was set; otherwise, /// false. /// is a /// negative number other than -1, which represents an infinite time-out. The current instance has already been /// disposed. public bool Wait(int millisecondsTimeout) { return Wait(millisecondsTimeout, new CancellationToken()); } ////// Blocks the current thread until the /// The number of milliseconds to wait, oris set, using a /// 32-bit signed integer to measure the time interval, while observing a /// . /// (-1) to wait indefinitely. /// The to /// observe. /// true if the ///was set; otherwise, /// false. /// is a /// negative number other than -1, which represents an infinite time-out. The current instance has already been /// disposed. ///public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) { if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("millisecondsTimeout"); } ThrowIfDisposed(); cancellationToken.ThrowIfCancellationRequested(); bool returnValue = IsSet; // If not completed yet, wait on the event. if (!returnValue) { // ** the actual wait returnValue = m_event.Wait(millisecondsTimeout, cancellationToken); //the Wait will throw OCE itself if the token is canceled. } return returnValue; } // -------------------------------------- // Private methods /// has /// been canceled. /// Throws an exception if the latch has been disposed. /// private void ThrowIfDisposed() { if (m_disposed) { throw new ObjectDisposedException("CountdownEvent"); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // // CountdownEvent.cs // //[....] // // A simple coordination data structure that we use for fork/join style parallelism. // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System; using System.Diagnostics; using System.Security.Permissions; using System.Runtime.InteropServices; using System.Threading; using System.Diagnostics.Contracts; namespace System.Threading { ////// Represents a synchronization primitive that is signaled when its count reaches zero. /// ////// All public and protected members of [ComVisible(false)] [DebuggerDisplay("Initial Count={InitialCount}, Current Count={CurrentCount}")] [HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)] public class CountdownEvent : IDisposable { // CountdownEvent is a simple synchronization primitive used for fork/join parallelism. We create a // latch with a count of N; threads then signal the latch, which decrements N by 1; other threads can // wait on the latch at any point; when the latch count reaches 0, all threads are woken and // subsequent waiters return without waiting. The implementation internally lazily creates a true // Win32 event as needed. We also use some amount of spinning on MP machines before falling back to a // wait. private int m_initialCount; // The original # of signals the latch was instantiated with. private volatile int m_currentCount; // The # of outstanding signals before the latch transitions to a signaled state. private ManualResetEventSlim m_event; // An event used to manage blocking and signaling. private volatile bool m_disposed; // Whether the latch has been disposed. ///are thread-safe and may be used /// concurrently from multiple threads, with the exception of Dispose, which /// must only be used when all other operations on the have /// completed, and Reset, which should only be used when no other threads are /// accessing the event. /// /// Initializes a new instance of /// The number of signals required to set theclass with the /// specified count. /// . /// public CountdownEvent(int initialCount) { if (initialCount < 0) { throw new ArgumentOutOfRangeException("initialCount"); } m_initialCount = initialCount; m_currentCount = initialCount; // Allocate a thin event, which internally defers creation of an actual Win32 event. m_event = new ManualResetEventSlim(); // If the latch was created with a count of 0, then it's already in the signaled state. if (initialCount == 0) { m_event.Set(); } } /// is less /// than 0. /// Gets the number of remaining signals required to set the event. /// ////// The number of remaining signals required to set the event. /// public int CurrentCount { get { return m_currentCount; } } ////// Gets the numbers of signals initially required to set the event. /// ////// The number of signals initially required to set the event. /// public int InitialCount { get { return m_initialCount; } } ////// Determines whether the event is set. /// ///true if the event is set; otherwise, false. public bool IsSet { get { // The latch is "completed" if its current count has reached 0. Note that this is NOT // the same thing is checking the event's IsCompleted property. There is a tiny window // of time, after the final decrement of the current count to 0 and before setting the // event, where the two values are out of [....]. return (m_currentCount == 0); } } ////// Gets a ///that is used to wait for the event to be set. /// A ///that is used to wait for the event to be set. The current instance has already been disposed. ////// public WaitHandle WaitHandle { get { ThrowIfDisposed(); return m_event.WaitHandle; } } ///should only be used if it's needed for integration with code bases /// that rely on having a WaitHandle. If all that's needed is to wait for the /// to be set, the method should be preferred. /// /// Releases all resources used by the current instance of ///. /// /// Unlike most of the members of public void Dispose() { // Gets rid of this latch's associated resources. This can consist of a Win32 event // which is (lazily) allocated by the underlying thin event. This method is not safe to // call concurrently -- i.e. a caller must coordinate to ensure only one thread is using // the latch at the time of the call to Dispose. Dispose(true); GC.SuppressFinalize(this); } ///, is not /// thread-safe and may not be used concurrently with other members of this instance. /// /// When overridden in a derived class, releases the unmanaged resources used by the /// /// true to release both managed and unmanaged resources; false to release /// only unmanaged resources. ///, and optionally releases the managed resources. /// /// Unlike most of the members of protected virtual void Dispose(bool disposing) { if (disposing) { m_event.Dispose(); m_disposed = true; } } ///, is not /// thread-safe and may not be used concurrently with other members of this instance. /// /// Registers a signal with the ///, decrementing its /// count. /// true if the signal caused the count to reach zero and the event was set; otherwise, /// false. ///The current instance is already set. /// ///The current instance has already been /// disposed. public bool Signal() { return Signal(1); } ////// Registers multiple signals with the /// The number of signals to register. ///, /// decrementing its count by the specified amount. /// true if the signals caused the count to reach zero and the event was set; otherwise, /// false. ////// The current instance is already set. -or- Or ///is greater than . /// /// is less /// than 1. The current instance has already been /// disposed. public bool Signal(int signalCount) { if (signalCount <= 0) { throw new ArgumentOutOfRangeException("signalCount"); } ThrowIfDisposed(); Contract.Assert(m_event != null); int observedCount; SpinWait spin = new SpinWait(); while (true) { observedCount = m_currentCount; // If the latch is already signaled, we will fail. if (observedCount < signalCount) { throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Decrement_BelowZero")); } // This disables the "CS0420: a reference to a volatile field will not be treated as volatile" warning // for this statement. This warning is clearly senseless for Interlocked operations. #pragma warning disable 0420 if (Interlocked.CompareExchange(ref m_currentCount, observedCount - signalCount, observedCount) == observedCount) #pragma warning restore 0420 { break; } // The CAS failed. Spin briefly and try again. spin.SpinOnce(); } // If we were the last to signal, set the event. if (observedCount == signalCount) { m_event.Set(); return true; } Contract.Assert(m_currentCount >= 0, "latch was decremented below zero"); return false; } ////// Increments the ///'s current count by one. /// The current instance is already /// set. ////// is equal to . /// The current instance has already been disposed. /// public void AddCount() { AddCount(1); } ////// Attempts to increment the ///'s current count by one. /// true if the increment succeeded; otherwise, false. If ///is /// already at zero. this will return false. /// is equal to . The current instance has already been /// disposed. public bool TryAddCount() { return TryAddCount(1); } ////// Increments the /// The value by which to increase's current count by a specified /// value. /// . /// /// is less than /// 0. The current instance is already /// set. ////// is equal to . The current instance has already been /// disposed. public void AddCount(int signalCount) { if (!TryAddCount(signalCount)) { throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Increment_AlreadyZero")); } } ////// Attempts to increment the /// The value by which to increase's current count by a /// specified value. /// . /// true if the increment succeeded; otherwise, false. If ///is /// already at zero this will return false. /// is less /// than 0. The current instance is already /// set. ////// is equal to . The current instance has already been /// disposed. public bool TryAddCount(int signalCount) { if (signalCount <= 0) { throw new ArgumentOutOfRangeException("signalCount"); } ThrowIfDisposed(); // Loop around until we successfully increment the count. int observedCount; SpinWait spin = new SpinWait(); while (true) { observedCount = m_currentCount; if (observedCount == 0) { return false; } else if (observedCount > (Int32.MaxValue - signalCount)) { throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Increment_AlreadyMax")); } // This disables the "CS0420: a reference to a volatile field will not be treated as volatile" warning // for this statement. This warning is clearly senseless for Interlocked operations. #pragma warning disable 0420 if (Interlocked.CompareExchange(ref m_currentCount, observedCount + signalCount, observedCount) == observedCount) #pragma warning restore 0420 { break; } // The CAS failed. Spin briefly and try again. spin.SpinOnce(); } return true; } ////// Resets the ///to the value of . /// /// Unlike most of the members of ///, Reset is not /// thread-safe and may not be used concurrently with other members of this instance. /// The current instance has already been /// disposed.. public void Reset() { Reset(m_initialCount); } ////// Resets the /// The number of signals required to set theto a specified value. /// . /// /// Unlike most of the members of ///, Reset is not /// thread-safe and may not be used concurrently with other members of this instance. /// /// is /// less than 0. The current instance has alread been disposed. public void Reset(int count) { ThrowIfDisposed(); if (count < 0) { throw new ArgumentOutOfRangeException("count"); } m_currentCount = count; m_initialCount = count; if (count == 0) { m_event.Set(); } else { m_event.Reset(); } } ////// Blocks the current thread until the ///is set. /// /// The caller of this method blocks indefinitely until the current instance is set. The caller will /// return immediately if the event is currently in a set state. /// ///The current instance has already been /// disposed. public void Wait() { Wait(Timeout.Infinite, new CancellationToken()); } ////// Blocks the current thread until the /// Theis set, while /// observing a . /// to /// observe. /// /// The caller of this method blocks indefinitely until the current instance is set. The caller will /// return immediately if the event is currently in a set state. If the /// ///CancellationToken being observed /// is canceled during the wait operation, an/// will be thrown. /// /// has been /// canceled. The current instance has already been /// disposed. public void Wait(CancellationToken cancellationToken) { Wait(Timeout.Infinite, cancellationToken); } ////// Blocks the current thread until the /// Ais set, using a /// to measure the time interval. /// that represents the number of /// milliseconds to wait, or a that represents -1 milliseconds to /// wait indefinitely. /// true if the ///was set; otherwise, /// false. /// is a negative /// number other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater /// than . The current instance has already been /// disposed. public bool Wait(TimeSpan timeout) { long totalMilliseconds = (long)timeout.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { throw new ArgumentOutOfRangeException("timeout"); } return Wait((int)totalMilliseconds, new CancellationToken()); } ////// Blocks the current thread until the /// Ais set, using /// a to measure the time interval, while observing a /// . /// that represents the number of /// milliseconds to wait, or a that represents -1 milliseconds to /// wait indefinitely. /// The to /// observe. /// true if the ///was set; otherwise, /// false. /// is a negative /// number other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater /// than . The current instance has already been /// disposed. ///public bool Wait(TimeSpan timeout, CancellationToken cancellationToken) { long totalMilliseconds = (long)timeout.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { throw new ArgumentOutOfRangeException("timeout"); } return Wait((int)totalMilliseconds, cancellationToken); } /// has /// been canceled. /// Blocks the current thread until the /// The number of milliseconds to wait, oris set, using a /// 32-bit signed integer to measure the time interval. /// (-1) to wait indefinitely. /// true if the ///was set; otherwise, /// false. /// is a /// negative number other than -1, which represents an infinite time-out. The current instance has already been /// disposed. public bool Wait(int millisecondsTimeout) { return Wait(millisecondsTimeout, new CancellationToken()); } ////// Blocks the current thread until the /// The number of milliseconds to wait, oris set, using a /// 32-bit signed integer to measure the time interval, while observing a /// . /// (-1) to wait indefinitely. /// The to /// observe. /// true if the ///was set; otherwise, /// false. /// is a /// negative number other than -1, which represents an infinite time-out. The current instance has already been /// disposed. ///public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) { if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("millisecondsTimeout"); } ThrowIfDisposed(); cancellationToken.ThrowIfCancellationRequested(); bool returnValue = IsSet; // If not completed yet, wait on the event. if (!returnValue) { // ** the actual wait returnValue = m_event.Wait(millisecondsTimeout, cancellationToken); //the Wait will throw OCE itself if the token is canceled. } return returnValue; } // -------------------------------------- // Private methods /// has /// been canceled. /// Throws an exception if the latch has been disposed. /// private void ThrowIfDisposed() { if (m_disposed) { throw new ObjectDisposedException("CountdownEvent"); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- MSAAWinEventWrap.cs
- CachedPathData.cs
- FirstMatchCodeGroup.cs
- FlatButtonAppearance.cs
- GiveFeedbackEventArgs.cs
- MouseOverProperty.cs
- AuthorizationRule.cs
- Debug.cs
- CounterSampleCalculator.cs
- TypeGeneratedEventArgs.cs
- WaitHandleCannotBeOpenedException.cs
- ListBindableAttribute.cs
- WebEventCodes.cs
- ValueExpressions.cs
- BoolLiteral.cs
- mediaclock.cs
- SystemIcmpV4Statistics.cs
- EdmToObjectNamespaceMap.cs
- SmtpFailedRecipientException.cs
- SQLInt16.cs
- DataGridViewAutoSizeModeEventArgs.cs
- VariableQuery.cs
- DecimalStorage.cs
- _ContextAwareResult.cs
- GeneratedCodeAttribute.cs
- InheritedPropertyChangedEventArgs.cs
- BitmapInitialize.cs
- FileDetails.cs
- SharedPersonalizationStateInfo.cs
- Animatable.cs
- MembershipSection.cs
- StringReader.cs
- CodeAssignStatement.cs
- WebScriptServiceHost.cs
- ScriptResourceInfo.cs
- PointCollection.cs
- XmlHierarchyData.cs
- ExecutionScope.cs
- QilInvokeEarlyBound.cs
- XPathDocumentBuilder.cs
- ButtonBaseAutomationPeer.cs
- ResXBuildProvider.cs
- SpecialFolderEnumConverter.cs
- NestPullup.cs
- EventEntry.cs
- ExpressionDumper.cs
- GraphicsContext.cs
- FormViewModeEventArgs.cs
- Base64Decoder.cs
- StoreContentChangedEventArgs.cs
- TypeGeneratedEventArgs.cs
- StructuredTypeEmitter.cs
- ObjectStateEntryDbUpdatableDataRecord.cs
- SchemaCompiler.cs
- BamlWriter.cs
- CodeEntryPointMethod.cs
- DataBindingHandlerAttribute.cs
- TransferRequestHandler.cs
- FlowNode.cs
- xdrvalidator.cs
- InfoCardAsymmetricCrypto.cs
- DataGridViewDataConnection.cs
- ExpanderAutomationPeer.cs
- DataAdapter.cs
- PathGradientBrush.cs
- UsernameTokenFactoryCredential.cs
- AsyncOperationManager.cs
- GridEntry.cs
- ToolbarAUtomationPeer.cs
- IDReferencePropertyAttribute.cs
- Canvas.cs
- FontUnitConverter.cs
- X509ServiceCertificateAuthentication.cs
- XPathNodeIterator.cs
- PrintPreviewControl.cs
- WebPartCloseVerb.cs
- ContentValidator.cs
- WebPartVerbCollection.cs
- ImageSourceConverter.cs
- CodePrimitiveExpression.cs
- DateTimeFormatInfoScanner.cs
- WebPartConnection.cs
- FormParameter.cs
- ReliabilityContractAttribute.cs
- LinqDataSourceValidationException.cs
- WindowsEditBoxRange.cs
- RuntimeArgumentHandle.cs
- CodeCompiler.cs
- NativeRecognizer.cs
- XPathNavigator.cs
- LinqDataSourceUpdateEventArgs.cs
- formatter.cs
- ImageListUtils.cs
- HtmlWindowCollection.cs
- MDIWindowDialog.cs
- WebColorConverter.cs
- Code.cs
- ZipIOEndOfCentralDirectoryBlock.cs
- UrlMapping.cs
- AttributeAction.cs