Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Threading / Tasks / TaskExtensions.cs / 1305376 / TaskExtensions.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // // TaskExtensions.cs // //[....] // // Extensions to Task/Taskclasses // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using System.Diagnostics.Contracts; namespace System.Threading.Tasks { /// /// Provides a set of static (Shared in Visual Basic) methods for working with specific kinds of /// public static class TaskExtensions { ///instances. /// /// Creates a proxy ///Task that represents the /// asynchronous operation of a Task{Task}. ////// It is often useful to be able to return a Task from a /// The Task{Task} to unwrap. ////// Task{TResult} , where the inner Task represents work done as part of the outer Task{TResult}. However, /// doing so results in a Task{Task}, which, if not dealt with carefully, could produce unexpected behavior. Unwrap /// solves this problem by creating a proxy Task that represents the entire asynchronous operation of such a Task{Task}. ///The exception that is thrown if the /// ///argument is null. A Task that represents the asynchronous operation of the provided Task{Task}. public static Task Unwrap(this Tasktask) { if (task == null) throw new ArgumentNullException("task"); bool result; // tcs.Task serves as a proxy for task.Result. // AttachedToParent is the only legal option for TCS-style task. var tcs = new TaskCompletionSource (task.CreationOptions & TaskCreationOptions.AttachedToParent); // Set up some actions to take when task has completed. task.ContinueWith(delegate { switch (task.Status) { // If task did not run to completion, then record the cancellation/fault information // to tcs.Task. case TaskStatus.Canceled: case TaskStatus.Faulted: result = tcs.TrySetFromTask(task); Contract.Assert(result, "Unwrap(Task ): Expected TrySetFromTask #1 to succeed"); break; case TaskStatus.RanToCompletion: // task.Result == null ==> proxy should be canceled. if (task.Result == null) tcs.TrySetCanceled(); // When task.Result completes, take some action to set the completion state of tcs.Task. else { task.Result.ContinueWith(_ => { // Copy completion/cancellation/exception info from task.Result to tcs.Task. result = tcs.TrySetFromTask(task.Result); Contract.Assert(result, "Unwrap(Task ): Expected TrySetFromTask #2 to succeed"); }, TaskContinuationOptions.ExecuteSynchronously).ContinueWith(antecedent => { // Clean up if ContinueWith() operation fails due to TSE tcs.TrySetException(antecedent.Exception); }, TaskContinuationOptions.OnlyOnFaulted); } break; } }, TaskContinuationOptions.ExecuteSynchronously).ContinueWith(antecedent => { // Clean up if ContinueWith() operation fails due to TSE tcs.TrySetException(antecedent.Exception); }, TaskContinuationOptions.OnlyOnFaulted); // Return this immediately as a proxy. When task.Result completes, or task is faulted/canceled, // the completion information will be transfered to tcs.Task. return tcs.Task; } /// /// Creates a proxy ///Task{TResult} that represents the /// asynchronous operation of a Task{Task{TResult}}. ////// It is often useful to be able to return a Task{TResult} from a Task{TResult}, where the inner Task{TResult} /// represents work done as part of the outer Task{TResult}. However, doing so results in a Task{Task{TResult}}, /// which, if not dealt with carefully, could produce unexpected behavior. Unwrap solves this problem by /// creating a proxy Task{TResult} that represents the entire asynchronous operation of such a Task{Task{TResult}}. /// /// The Task{Task{TResult}} to unwrap. ///The exception that is thrown if the /// ///argument is null. A Task{TResult} that represents the asynchronous operation of the provided Task{Task{TResult}}. ///Unwraps a Task that returns another Task. public static TaskUnwrap (this Task > task) { if (task == null) throw new ArgumentNullException("task"); bool result; // tcs.Task serves as a proxy for task.Result. // AttachedToParent is the only legal option for TCS-style task. var tcs = new TaskCompletionSource (task.CreationOptions & TaskCreationOptions.AttachedToParent); // Set up some actions to take when task has completed. task.ContinueWith(delegate { switch (task.Status) { // If task did not run to completion, then record the cancellation/fault information // to tcs.Task. case TaskStatus.Canceled: case TaskStatus.Faulted: result = tcs.TrySetFromTask(task); Contract.Assert(result, "Unwrap(Task >): Expected TrySetFromTask #1 to succeed"); break; case TaskStatus.RanToCompletion: // task.Result == null ==> proxy should be canceled. if (task.Result == null) tcs.TrySetCanceled(); // When task.Result completes, take some action to set the completion state of tcs.Task. else { task.Result.ContinueWith(_ => { // Copy completion/cancellation/exception info from task.Result to tcs.Task. result = tcs.TrySetFromTask(task.Result); Contract.Assert(result, "Unwrap(Task >): Expected TrySetFromTask #2 to succeed"); }, TaskContinuationOptions.ExecuteSynchronously).ContinueWith(antecedent => { // Clean up if ContinueWith() operation fails due to TSE tcs.TrySetException(antecedent.Exception); }, TaskContinuationOptions.OnlyOnFaulted); } break; } }, TaskContinuationOptions.ExecuteSynchronously).ContinueWith(antecedent => { // Clean up if ContinueWith() operation fails due to TSE tcs.TrySetException(antecedent.Exception); }, TaskContinuationOptions.OnlyOnFaulted); ; // Return this immediately as a proxy. When task.Result completes, or task is faulted/canceled, // the completion information will be transfered to tcs.Task. return tcs.Task; } // Transfer the completion status from "source" to "me". private static bool TrySetFromTask (this TaskCompletionSource me, Task source) { Contract.Assert(source.IsCompleted, "TrySetFromTask: Expected source to have completed."); bool rval = false; switch(source.Status) { case TaskStatus.Canceled: rval = me.TrySetCanceled(); break; case TaskStatus.Faulted: rval = me.TrySetException(source.Exception.InnerExceptions); break; case TaskStatus.RanToCompletion: if(source is Task ) rval = me.TrySetResult( ((Task )source).Result); else rval = me.TrySetResult(default(TResult)); break; } return rval; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // // TaskExtensions.cs // // [....] // // Extensions to Task/Taskclasses // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using System.Diagnostics.Contracts; namespace System.Threading.Tasks { /// /// Provides a set of static (Shared in Visual Basic) methods for working with specific kinds of /// public static class TaskExtensions { ///instances. /// /// Creates a proxy ///Task that represents the /// asynchronous operation of a Task{Task}. ////// It is often useful to be able to return a Task from a /// The Task{Task} to unwrap. ////// Task{TResult} , where the inner Task represents work done as part of the outer Task{TResult}. However, /// doing so results in a Task{Task}, which, if not dealt with carefully, could produce unexpected behavior. Unwrap /// solves this problem by creating a proxy Task that represents the entire asynchronous operation of such a Task{Task}. ///The exception that is thrown if the /// ///argument is null. A Task that represents the asynchronous operation of the provided Task{Task}. public static Task Unwrap(this Tasktask) { if (task == null) throw new ArgumentNullException("task"); bool result; // tcs.Task serves as a proxy for task.Result. // AttachedToParent is the only legal option for TCS-style task. var tcs = new TaskCompletionSource (task.CreationOptions & TaskCreationOptions.AttachedToParent); // Set up some actions to take when task has completed. task.ContinueWith(delegate { switch (task.Status) { // If task did not run to completion, then record the cancellation/fault information // to tcs.Task. case TaskStatus.Canceled: case TaskStatus.Faulted: result = tcs.TrySetFromTask(task); Contract.Assert(result, "Unwrap(Task ): Expected TrySetFromTask #1 to succeed"); break; case TaskStatus.RanToCompletion: // task.Result == null ==> proxy should be canceled. if (task.Result == null) tcs.TrySetCanceled(); // When task.Result completes, take some action to set the completion state of tcs.Task. else { task.Result.ContinueWith(_ => { // Copy completion/cancellation/exception info from task.Result to tcs.Task. result = tcs.TrySetFromTask(task.Result); Contract.Assert(result, "Unwrap(Task ): Expected TrySetFromTask #2 to succeed"); }, TaskContinuationOptions.ExecuteSynchronously).ContinueWith(antecedent => { // Clean up if ContinueWith() operation fails due to TSE tcs.TrySetException(antecedent.Exception); }, TaskContinuationOptions.OnlyOnFaulted); } break; } }, TaskContinuationOptions.ExecuteSynchronously).ContinueWith(antecedent => { // Clean up if ContinueWith() operation fails due to TSE tcs.TrySetException(antecedent.Exception); }, TaskContinuationOptions.OnlyOnFaulted); // Return this immediately as a proxy. When task.Result completes, or task is faulted/canceled, // the completion information will be transfered to tcs.Task. return tcs.Task; } /// /// Creates a proxy ///Task{TResult} that represents the /// asynchronous operation of a Task{Task{TResult}}. ////// It is often useful to be able to return a Task{TResult} from a Task{TResult}, where the inner Task{TResult} /// represents work done as part of the outer Task{TResult}. However, doing so results in a Task{Task{TResult}}, /// which, if not dealt with carefully, could produce unexpected behavior. Unwrap solves this problem by /// creating a proxy Task{TResult} that represents the entire asynchronous operation of such a Task{Task{TResult}}. /// /// The Task{Task{TResult}} to unwrap. ///The exception that is thrown if the /// ///argument is null. A Task{TResult} that represents the asynchronous operation of the provided Task{Task{TResult}}. ///Unwraps a Task that returns another Task. public static TaskUnwrap (this Task > task) { if (task == null) throw new ArgumentNullException("task"); bool result; // tcs.Task serves as a proxy for task.Result. // AttachedToParent is the only legal option for TCS-style task. var tcs = new TaskCompletionSource (task.CreationOptions & TaskCreationOptions.AttachedToParent); // Set up some actions to take when task has completed. task.ContinueWith(delegate { switch (task.Status) { // If task did not run to completion, then record the cancellation/fault information // to tcs.Task. case TaskStatus.Canceled: case TaskStatus.Faulted: result = tcs.TrySetFromTask(task); Contract.Assert(result, "Unwrap(Task >): Expected TrySetFromTask #1 to succeed"); break; case TaskStatus.RanToCompletion: // task.Result == null ==> proxy should be canceled. if (task.Result == null) tcs.TrySetCanceled(); // When task.Result completes, take some action to set the completion state of tcs.Task. else { task.Result.ContinueWith(_ => { // Copy completion/cancellation/exception info from task.Result to tcs.Task. result = tcs.TrySetFromTask(task.Result); Contract.Assert(result, "Unwrap(Task >): Expected TrySetFromTask #2 to succeed"); }, TaskContinuationOptions.ExecuteSynchronously).ContinueWith(antecedent => { // Clean up if ContinueWith() operation fails due to TSE tcs.TrySetException(antecedent.Exception); }, TaskContinuationOptions.OnlyOnFaulted); } break; } }, TaskContinuationOptions.ExecuteSynchronously).ContinueWith(antecedent => { // Clean up if ContinueWith() operation fails due to TSE tcs.TrySetException(antecedent.Exception); }, TaskContinuationOptions.OnlyOnFaulted); ; // Return this immediately as a proxy. When task.Result completes, or task is faulted/canceled, // the completion information will be transfered to tcs.Task. return tcs.Task; } // Transfer the completion status from "source" to "me". private static bool TrySetFromTask (this TaskCompletionSource me, Task source) { Contract.Assert(source.IsCompleted, "TrySetFromTask: Expected source to have completed."); bool rval = false; switch(source.Status) { case TaskStatus.Canceled: rval = me.TrySetCanceled(); break; case TaskStatus.Faulted: rval = me.TrySetException(source.Exception.InnerExceptions); break; case TaskStatus.RanToCompletion: if(source is Task ) rval = me.TrySetResult( ((Task )source).Result); else rval = me.TrySetResult(default(TResult)); break; } return rval; } } } // 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
- ConsoleCancelEventArgs.cs
- InternalBase.cs
- TabletDeviceInfo.cs
- StringCollectionEditor.cs
- BufferedStream.cs
- StructuredTypeEmitter.cs
- DbProviderFactory.cs
- WebPartConnectionsEventArgs.cs
- SmtpClient.cs
- Environment.cs
- DetailsViewDeleteEventArgs.cs
- AsyncPostBackErrorEventArgs.cs
- Label.cs
- QueryPrefixOp.cs
- DefaultBindingPropertyAttribute.cs
- X509Certificate.cs
- MissingSatelliteAssemblyException.cs
- QuerySelectOp.cs
- FontCacheUtil.cs
- SQLInt64.cs
- ListBoxAutomationPeer.cs
- QueryOperator.cs
- WebPermission.cs
- DocumentScope.cs
- FormViewRow.cs
- EntityContainerEntitySet.cs
- UIElementParagraph.cs
- OdbcDataAdapter.cs
- ControlBindingsCollection.cs
- BStrWrapper.cs
- LocationSectionRecord.cs
- LocalizationComments.cs
- TraversalRequest.cs
- EventLogger.cs
- BidOverLoads.cs
- EventListener.cs
- DataListItemEventArgs.cs
- XsltLoader.cs
- ListBindingConverter.cs
- XamlStackWriter.cs
- WindowsSpinner.cs
- XmlDocumentViewSchema.cs
- FlagsAttribute.cs
- WinCategoryAttribute.cs
- FilterQuery.cs
- HwndMouseInputProvider.cs
- DbParameterHelper.cs
- AcceleratedTokenProviderState.cs
- ExtenderProvidedPropertyAttribute.cs
- PolyQuadraticBezierSegmentFigureLogic.cs
- WebException.cs
- TemplatePartAttribute.cs
- TreePrinter.cs
- ReplyAdapterChannelListener.cs
- XmlSchemaSimpleTypeUnion.cs
- SerializationObjectManager.cs
- ContentValidator.cs
- MenuAutomationPeer.cs
- FormViewUpdatedEventArgs.cs
- UriScheme.cs
- EdmItemCollection.OcAssemblyCache.cs
- IntegrationExceptionEventArgs.cs
- ToolBarPanel.cs
- BitmapEffectDrawingContextWalker.cs
- ActivityExecutorSurrogate.cs
- IndexedGlyphRun.cs
- DiscoveryClientProtocol.cs
- RowToParametersTransformer.cs
- TextWriterEngine.cs
- SyntaxCheck.cs
- Latin1Encoding.cs
- HwndKeyboardInputProvider.cs
- InfoCardSymmetricAlgorithm.cs
- VBCodeProvider.cs
- SourceLineInfo.cs
- XmlWhitespace.cs
- UpdateInfo.cs
- XmlNamespaceMappingCollection.cs
- DrawingVisualDrawingContext.cs
- TemplateNameScope.cs
- JsonXmlDataContract.cs
- WebPartEditorCancelVerb.cs
- XmlSchemaExternal.cs
- CodeSubDirectory.cs
- SettingsPropertyValueCollection.cs
- SqlRowUpdatedEvent.cs
- TranslateTransform3D.cs
- HttpServerVarsCollection.cs
- HuffModule.cs
- MetadataProperty.cs
- ConfigurationValidatorAttribute.cs
- NameValuePair.cs
- EpmAttributeNameBuilder.cs
- EditCommandColumn.cs
- DataGridViewDataErrorEventArgs.cs
- _AutoWebProxyScriptEngine.cs
- UserControlFileEditor.cs
- DeferredReference.cs
- SrgsOneOf.cs
- DragDrop.cs