Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataWeb / Client / System / Data / Services / Client / BaseAsyncResult.cs / 2 / BaseAsyncResult.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // //// query object // //--------------------------------------------------------------------- namespace System.Data.Services.Client { using System; using System.Diagnostics; using System.IO; #if !ASTORIA_LIGHT // Data.Services http stack using System.Net; #else using System.Data.Services.Http; #endif ////// Implementation of IAsyncResult /// internal abstract class BaseAsyncResult : IAsyncResult { ///Originating object, used to validate End* internal readonly object Source; ///Originating method on source, to differentiate between different methods from same source internal readonly string Method; ///User callback passed to Begin* private readonly AsyncCallback userCallback; ///User state passed to Begin* private readonly object userState; ///wait handle for user to wait until done private System.Threading.ManualResetEvent asyncWait; ///Holding exception to throw as a nested exception during to End* private Exception failure; ///true unless something completes asynchronously private bool completedSynchronously = true; ///true when really completed for the user private bool userCompleted; ///true when no more changes are pending, 0 false, 1 completed, 2 aborted private int completed; ///verify we only invoke the user callback once, 0 false, 1 true private int userNotified; ///non-zero after End*, 0 false, 1, true private int done; ////// ctor /// /// source object of async request /// async method name on source object /// user callback to invoke when complete /// user state internal BaseAsyncResult(object source, string method, AsyncCallback callback, object state) { Debug.Assert(null != source, "null source"); this.Source = source; this.Method = method; this.userCallback = callback; this.userState = state; } #region IAsyncResult implmentation - AsyncState, AsyncWaitHandle, CompletedSynchronously, IsCompleted ///user state object parameter public object AsyncState { get { return this.userState; } } ///wait handle for when waiting is required ///if displayed by debugger, it undesirable to create the WaitHandle [DebuggerBrowsable(DebuggerBrowsableState.Never)] public System.Threading.WaitHandle AsyncWaitHandle { get { if (null == this.asyncWait) { // delay create the wait handle since the user may never use it // like asyncWait which will be GC'd, the losers in creating the asyncWait will also be GC'd System.Threading.Interlocked.CompareExchange(ref this.asyncWait, new System.Threading.ManualResetEvent(this.IsCompleted), null); // multi-thread condition // 1) thread 1 returned IAsyncResult and !IsCompleted so AsyncWaitHandle.WaitOne() // 2) thread 2 signals complete, however thread 1 has retrieved this.completed but not assigned asyncWait if (this.IsCompleted) { // yes, Set may be called multiple times - but user would have to assume ManualResetEvent and call Reset this.asyncWait.Set(); } } return this.asyncWait; } } ///did the result complete synchronously? public bool CompletedSynchronously { get { return this.completedSynchronously; } internal set { this.completedSynchronously = value; } } ///is the result complete? public bool IsCompleted { get { return this.userCompleted; } } ///is the result complete? internal bool IsCompletedInternally { get { return (0 != this.completed); } } #endregion ///first exception that happened internal Exception Failure { get { return this.failure; } } ////// common handler for EndExecuteBatch & EndSaveChanges /// ///derived type of the AsyncResult /// source object of async request /// async method name on source object /// the asyncResult being ended ///data service response for batch internal static T EndExecute(object source, string method, IAsyncResult asyncResult) where T : BaseAsyncResult { Util.CheckArgumentNull(asyncResult, "asyncResult"); T result = (asyncResult as T); if ((null == result) || (source != result.Source) || (result.Method != method)) { throw Error.Argument(Strings.Context_DidNotOriginateAsync, "asyncResult"); } Debug.Assert((result.CompletedSynchronously && result.IsCompleted) || !result.CompletedSynchronously, "CompletedSynchronously && !IsCompleted"); if (!result.IsCompleted) { // if the user doesn't want to wait forever, they should explictly wait on the handle with a timeout result.AsyncWaitHandle.WaitOne(); Debug.Assert(result.IsCompleted, "not completed after waiting"); } if (System.Threading.Interlocked.Exchange(ref result.done, 1) != 0) { throw Error.Argument(Strings.Context_AsyncAlreadyDone, "asyncResult"); } if (null != result.failure) { throw Error.InvalidOperation(Strings.Context_SaveChangesError, result.failure); } return result; } /// Set the AsyncWait and invoke the user callback. ////// If the background thread gets a ThreadAbort, the userCallback will never be invoked. /// This is why it's generally important to never wait forever, but to have more specific /// time limit. Also then cancel the operation, to make sure its stopped, to avoid /// multi-threading if your wait time limit was just too short. /// internal void HandleCompleted() { if (Util.DoNotHandleException(this.failure)) { return; } if (this.IsCompletedInternally && (System.Threading.Interlocked.Exchange(ref this.userNotified, 1) == 0)) { try { // the CompleteRequest may do additional work which is why // it is important not to signal the user via either the // IAsyncResult.IsCompleted, IAsyncResult.WaitHandle or the callback this.CompletedRequest(); } catch (Exception ex) { if (this.HandleFailure(ex)) { throw; } } // 1. set IAsyncResult.IsCompleted, otherwise user was // signalled on another thread, but the property may not be true. this.userCompleted = true; // 2. signal the wait handle because it can't be first nor can it be last. if (null != this.asyncWait) { this.asyncWait.Set(); } // 3. invoke the callback because user may throw an exception and stop any further processing if (null != this.userCallback) { // any exception thrown by user should be "unhandled" // it's possible callback will be invoked while another creates and sets the asyncWait this.userCallback(this); } } } ///Cache the exception that happened on the background thread for the caller of EndSaveChanges. /// exception object from background thread ///true if the exception (like StackOverflow or ThreadAbort) should be rethrown internal bool HandleFailure(Exception e) { System.Threading.Interlocked.CompareExchange(ref this.failure, e, null); this.SetCompleted(); return Util.DoNotHandleException(e); } ///Set the async result as completed. internal void SetCompleted() { System.Threading.Interlocked.CompareExchange(ref this.completed, 1, 0); } ///invoked for derived classes to cleanup before callback is invoked protected abstract void CompletedRequest(); } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // //// query object // //--------------------------------------------------------------------- namespace System.Data.Services.Client { using System; using System.Diagnostics; using System.IO; #if !ASTORIA_LIGHT // Data.Services http stack using System.Net; #else using System.Data.Services.Http; #endif ////// Implementation of IAsyncResult /// internal abstract class BaseAsyncResult : IAsyncResult { ///Originating object, used to validate End* internal readonly object Source; ///Originating method on source, to differentiate between different methods from same source internal readonly string Method; ///User callback passed to Begin* private readonly AsyncCallback userCallback; ///User state passed to Begin* private readonly object userState; ///wait handle for user to wait until done private System.Threading.ManualResetEvent asyncWait; ///Holding exception to throw as a nested exception during to End* private Exception failure; ///true unless something completes asynchronously private bool completedSynchronously = true; ///true when really completed for the user private bool userCompleted; ///true when no more changes are pending, 0 false, 1 completed, 2 aborted private int completed; ///verify we only invoke the user callback once, 0 false, 1 true private int userNotified; ///non-zero after End*, 0 false, 1, true private int done; ////// ctor /// /// source object of async request /// async method name on source object /// user callback to invoke when complete /// user state internal BaseAsyncResult(object source, string method, AsyncCallback callback, object state) { Debug.Assert(null != source, "null source"); this.Source = source; this.Method = method; this.userCallback = callback; this.userState = state; } #region IAsyncResult implmentation - AsyncState, AsyncWaitHandle, CompletedSynchronously, IsCompleted ///user state object parameter public object AsyncState { get { return this.userState; } } ///wait handle for when waiting is required ///if displayed by debugger, it undesirable to create the WaitHandle [DebuggerBrowsable(DebuggerBrowsableState.Never)] public System.Threading.WaitHandle AsyncWaitHandle { get { if (null == this.asyncWait) { // delay create the wait handle since the user may never use it // like asyncWait which will be GC'd, the losers in creating the asyncWait will also be GC'd System.Threading.Interlocked.CompareExchange(ref this.asyncWait, new System.Threading.ManualResetEvent(this.IsCompleted), null); // multi-thread condition // 1) thread 1 returned IAsyncResult and !IsCompleted so AsyncWaitHandle.WaitOne() // 2) thread 2 signals complete, however thread 1 has retrieved this.completed but not assigned asyncWait if (this.IsCompleted) { // yes, Set may be called multiple times - but user would have to assume ManualResetEvent and call Reset this.asyncWait.Set(); } } return this.asyncWait; } } ///did the result complete synchronously? public bool CompletedSynchronously { get { return this.completedSynchronously; } internal set { this.completedSynchronously = value; } } ///is the result complete? public bool IsCompleted { get { return this.userCompleted; } } ///is the result complete? internal bool IsCompletedInternally { get { return (0 != this.completed); } } #endregion ///first exception that happened internal Exception Failure { get { return this.failure; } } ////// common handler for EndExecuteBatch & EndSaveChanges /// ///derived type of the AsyncResult /// source object of async request /// async method name on source object /// the asyncResult being ended ///data service response for batch internal static T EndExecute(object source, string method, IAsyncResult asyncResult) where T : BaseAsyncResult { Util.CheckArgumentNull(asyncResult, "asyncResult"); T result = (asyncResult as T); if ((null == result) || (source != result.Source) || (result.Method != method)) { throw Error.Argument(Strings.Context_DidNotOriginateAsync, "asyncResult"); } Debug.Assert((result.CompletedSynchronously && result.IsCompleted) || !result.CompletedSynchronously, "CompletedSynchronously && !IsCompleted"); if (!result.IsCompleted) { // if the user doesn't want to wait forever, they should explictly wait on the handle with a timeout result.AsyncWaitHandle.WaitOne(); Debug.Assert(result.IsCompleted, "not completed after waiting"); } if (System.Threading.Interlocked.Exchange(ref result.done, 1) != 0) { throw Error.Argument(Strings.Context_AsyncAlreadyDone, "asyncResult"); } if (null != result.failure) { throw Error.InvalidOperation(Strings.Context_SaveChangesError, result.failure); } return result; } /// Set the AsyncWait and invoke the user callback. ////// If the background thread gets a ThreadAbort, the userCallback will never be invoked. /// This is why it's generally important to never wait forever, but to have more specific /// time limit. Also then cancel the operation, to make sure its stopped, to avoid /// multi-threading if your wait time limit was just too short. /// internal void HandleCompleted() { if (Util.DoNotHandleException(this.failure)) { return; } if (this.IsCompletedInternally && (System.Threading.Interlocked.Exchange(ref this.userNotified, 1) == 0)) { try { // the CompleteRequest may do additional work which is why // it is important not to signal the user via either the // IAsyncResult.IsCompleted, IAsyncResult.WaitHandle or the callback this.CompletedRequest(); } catch (Exception ex) { if (this.HandleFailure(ex)) { throw; } } // 1. set IAsyncResult.IsCompleted, otherwise user was // signalled on another thread, but the property may not be true. this.userCompleted = true; // 2. signal the wait handle because it can't be first nor can it be last. if (null != this.asyncWait) { this.asyncWait.Set(); } // 3. invoke the callback because user may throw an exception and stop any further processing if (null != this.userCallback) { // any exception thrown by user should be "unhandled" // it's possible callback will be invoked while another creates and sets the asyncWait this.userCallback(this); } } } ///Cache the exception that happened on the background thread for the caller of EndSaveChanges. /// exception object from background thread ///true if the exception (like StackOverflow or ThreadAbort) should be rethrown internal bool HandleFailure(Exception e) { System.Threading.Interlocked.CompareExchange(ref this.failure, e, null); this.SetCompleted(); return Util.DoNotHandleException(e); } ///Set the async result as completed. internal void SetCompleted() { System.Threading.Interlocked.CompareExchange(ref this.completed, 1, 0); } ///invoked for derived classes to cleanup before callback is invoked protected abstract void CompletedRequest(); } } // 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
- PointConverter.cs
- RequestSecurityTokenForRemoteTokenFactory.cs
- DocumentApplication.cs
- List.cs
- DecimalKeyFrameCollection.cs
- XmlDataContract.cs
- ListenerConnectionModeReader.cs
- RangeContentEnumerator.cs
- ConfigXmlWhitespace.cs
- ValidationRuleCollection.cs
- ContentDisposition.cs
- figurelength.cs
- DataGridViewButtonCell.cs
- TimelineCollection.cs
- Pair.cs
- RepeatBehavior.cs
- InProcStateClientManager.cs
- LabelEditEvent.cs
- RecognizerBase.cs
- TrackBarRenderer.cs
- CustomExpression.cs
- TraceEventCache.cs
- ServiceReflector.cs
- AsnEncodedData.cs
- HMACRIPEMD160.cs
- EdmItemCollection.OcAssemblyCache.cs
- XslAst.cs
- CorrelationToken.cs
- QueryInterceptorAttribute.cs
- NativeCompoundFileAPIs.cs
- StateFinalizationActivity.cs
- DataGridViewCellStyleEditor.cs
- OdbcConnectionStringbuilder.cs
- odbcmetadatafactory.cs
- FixedSOMTableCell.cs
- TextRangeBase.cs
- SoapIgnoreAttribute.cs
- MetaDataInfo.cs
- DnsElement.cs
- ResourcePropertyMemberCodeDomSerializer.cs
- TemplateXamlTreeBuilder.cs
- XPathChildIterator.cs
- RelatedPropertyManager.cs
- XmlQualifiedName.cs
- ApplicationSecurityManager.cs
- RsaSecurityTokenAuthenticator.cs
- BamlBinaryWriter.cs
- AttributeEmitter.cs
- XmlSchemaAttributeGroup.cs
- SimpleWorkerRequest.cs
- ProjectionCamera.cs
- SimpleMailWebEventProvider.cs
- DbProviderFactories.cs
- MailMessageEventArgs.cs
- EncoderParameters.cs
- EntityClassGenerator.cs
- ResourcesBuildProvider.cs
- GroupBoxAutomationPeer.cs
- SqlMetaData.cs
- DivideByZeroException.cs
- DataTransferEventArgs.cs
- DataFormats.cs
- TickBar.cs
- Odbc32.cs
- HtmlContainerControl.cs
- NodeLabelEditEvent.cs
- MobileControlsSectionHandler.cs
- ClientScriptItem.cs
- FormatSettings.cs
- DataGridViewCellParsingEventArgs.cs
- ClusterRegistryConfigurationProvider.cs
- RichTextBoxAutomationPeer.cs
- TimeSpanMinutesConverter.cs
- XmlSiteMapProvider.cs
- TaiwanCalendar.cs
- HttpContextServiceHost.cs
- UnaryNode.cs
- ListItemsPage.cs
- MediaCommands.cs
- precedingquery.cs
- XPathNode.cs
- SiteIdentityPermission.cs
- Int16Converter.cs
- PageBuildProvider.cs
- PriorityQueue.cs
- ToolStripRenderer.cs
- CodeActivity.cs
- ECDsa.cs
- ChannelRequirements.cs
- XmlAttributeAttribute.cs
- RemotingConfiguration.cs
- AttributeProviderAttribute.cs
- CustomMenuItemCollection.cs
- WebPartVerb.cs
- List.cs
- ObjectHelper.cs
- ReferencedCollectionType.cs
- TiffBitmapDecoder.cs
- ParsedAttributeCollection.cs
- SettingsPropertyValueCollection.cs