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
- Wizard.cs
- WebPartUserCapability.cs
- GridViewRowEventArgs.cs
- Lookup.cs
- StrokeRenderer.cs
- BinaryParser.cs
- SrgsNameValueTag.cs
- OracleDataAdapter.cs
- QuaternionRotation3D.cs
- CharUnicodeInfo.cs
- DefaultCompensation.cs
- SystemFonts.cs
- SecurityVersion.cs
- DataServiceEntityAttribute.cs
- TextBlock.cs
- CodeArgumentReferenceExpression.cs
- CompiledRegexRunnerFactory.cs
- ProfessionalColorTable.cs
- ConfigXmlCDataSection.cs
- ListSortDescriptionCollection.cs
- Baml2006KnownTypes.cs
- GuidTagList.cs
- SqlProcedureAttribute.cs
- sqlser.cs
- DiscoveryClientChannelBase.cs
- WebSysDefaultValueAttribute.cs
- FilterElement.cs
- DaylightTime.cs
- QueryExpression.cs
- TextDecorationCollection.cs
- AsyncContentLoadedEventArgs.cs
- EnumValAlphaComparer.cs
- InvokeHandlers.cs
- GridViewRowPresenter.cs
- VisualTreeUtils.cs
- CommandLibraryHelper.cs
- ArraySortHelper.cs
- BamlBinaryWriter.cs
- DBCSCodePageEncoding.cs
- SQLBoolean.cs
- FontNamesConverter.cs
- OleDbMetaDataFactory.cs
- DataRow.cs
- RegexBoyerMoore.cs
- DecoderNLS.cs
- Graphics.cs
- WebPartDisplayMode.cs
- ClientConfigurationSystem.cs
- BigInt.cs
- RC2CryptoServiceProvider.cs
- messageonlyhwndwrapper.cs
- GlobalAllocSafeHandle.cs
- IsolationInterop.cs
- EmptyQuery.cs
- BinaryObjectInfo.cs
- RoutedEventValueSerializer.cs
- InheritanceContextHelper.cs
- ToolStripActionList.cs
- ErrorTableItemStyle.cs
- SimpleFileLog.cs
- WmlListAdapter.cs
- TagMapInfo.cs
- HttpCapabilitiesBase.cs
- SqlConnectionPoolGroupProviderInfo.cs
- PrintEvent.cs
- DbParameterCollection.cs
- QilReference.cs
- embossbitmapeffect.cs
- Dictionary.cs
- MobileListItemCollection.cs
- PropertyGridEditorPart.cs
- ArgumentException.cs
- LicenseManager.cs
- TableLayoutSettings.cs
- HashSetDebugView.cs
- DataGridViewComponentPropertyGridSite.cs
- ItemsPanelTemplate.cs
- _Connection.cs
- SupportedAddressingMode.cs
- EntityDataSourceSelectingEventArgs.cs
- HtmlInputButton.cs
- WebContext.cs
- XmlValueConverter.cs
- WebScriptServiceHostFactory.cs
- SqlInternalConnectionTds.cs
- AttachedPropertyMethodSelector.cs
- FilterEventArgs.cs
- CodeTypeParameter.cs
- Part.cs
- TabControlEvent.cs
- ClassValidator.cs
- DesignerSerializerAttribute.cs
- WebPartConnectionsCancelVerb.cs
- log.cs
- COM2PropertyBuilderUITypeEditor.cs
- OleServicesContext.cs
- SendingRequestEventArgs.cs
- CatalogPartChrome.cs
- SafeHGlobalHandleCritical.cs
- BaseCodeDomTreeGenerator.cs