// // Task_T.cs // // Authors: // Marek Safar // // Copyright (c) 2008 Jérémie "Garuma" Laval // Copyright 2011 Xamarin Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // #if NET_4_0 || MOBILE using System.Runtime.CompilerServices; namespace System.Threading.Tasks { [System.Diagnostics.DebuggerDisplay ("Id = {Id}, Status = {Status}, Result = {ResultAsString}")] [System.Diagnostics.DebuggerTypeProxy (typeof (TaskDebuggerView))] public class Task : Task { static readonly TaskFactory factory = new TaskFactory (); TResult value; [System.Diagnostics.DebuggerBrowsable (System.Diagnostics.DebuggerBrowsableState.Never)] public TResult Result { get { if (!IsCompleted) Wait (); if (IsCanceled) throw new AggregateException (new TaskCanceledException (this)); if (Exception != null) throw Exception; return value; } internal set { this.value = value; } } string ResultAsString { get { if ((Status & (TaskStatus.RanToCompletion)) != 0) return "" + value; return ""; } } public static new TaskFactory Factory { get { return factory; } } public Task (Func function) : this (function, TaskCreationOptions.None) { } public Task (Func function, CancellationToken cancellationToken) : this (function, cancellationToken, TaskCreationOptions.None) { } public Task (Func function, TaskCreationOptions creationOptions) : this (function, CancellationToken.None, creationOptions) { } public Task (Func function, CancellationToken cancellationToken, TaskCreationOptions creationOptions) : base (TaskActionInvoker.Create (function), null, cancellationToken, creationOptions) { if (function == null) throw new ArgumentNullException ("function"); } public Task (Func function, object state) : this (function, state, TaskCreationOptions.None) { } public Task (Func function, object state, CancellationToken cancellationToken) : this (function, state, cancellationToken, TaskCreationOptions.None) { } public Task (Func function, object state, TaskCreationOptions creationOptions) : this (function, state, CancellationToken.None, creationOptions) { } public Task (Func function, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions) : base (TaskActionInvoker.Create (function), state, cancellationToken, creationOptions) { if (function == null) throw new ArgumentNullException ("function"); } internal Task (TaskActionInvoker invoker, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, Task parent, Task contAncestor = null) : base (invoker, state, cancellationToken, creationOptions, parent, contAncestor) { } public Task ContinueWith (Action> continuationAction) { return ContinueWith (continuationAction, TaskContinuationOptions.None); } public Task ContinueWith (Action> continuationAction, TaskContinuationOptions continuationOptions) { return ContinueWith (continuationAction, CancellationToken.None, continuationOptions, TaskScheduler.Current); } public Task ContinueWith (Action> continuationAction, CancellationToken cancellationToken) { return ContinueWith (continuationAction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current); } public Task ContinueWith (Action> continuationAction, TaskScheduler scheduler) { return ContinueWith (continuationAction, CancellationToken.None, TaskContinuationOptions.None, scheduler); } public Task ContinueWith (Action> continuationAction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { if (continuationAction == null) throw new ArgumentNullException ("continuationAction"); if (scheduler == null) throw new ArgumentNullException ("scheduler"); Task t = new Task (TaskActionInvoker.Create (continuationAction), null, cancellationToken, GetCreationOptions (continuationOptions), null, this); ContinueWithCore (t, continuationOptions, scheduler); return t; } public Task ContinueWith (Func, TNewResult> continuationFunction) { return ContinueWith (continuationFunction, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current); } public Task ContinueWith (Func, TNewResult> continuationFunction, CancellationToken cancellationToken) { return ContinueWith (continuationFunction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current); } public Task ContinueWith (Func, TNewResult> continuationFunction, TaskContinuationOptions continuationOptions) { return ContinueWith (continuationFunction, CancellationToken.None, continuationOptions, TaskScheduler.Current); } public Task ContinueWith (Func, TNewResult> continuationFunction, TaskScheduler scheduler) { return ContinueWith (continuationFunction, CancellationToken.None, TaskContinuationOptions.None, scheduler); } public Task ContinueWith (Func, TNewResult> continuationFunction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { if (continuationFunction == null) throw new ArgumentNullException ("continuationFunction"); if (scheduler == null) throw new ArgumentNullException ("scheduler"); var t = new Task (TaskActionInvoker.Create (continuationFunction), null, cancellationToken, GetCreationOptions (continuationOptions), null, this); ContinueWithCore (t, continuationOptions, scheduler); return t; } internal bool TrySetResult (TResult result) { if (IsCompleted) return false; if (!executing.TryRelaxedSet ()) { var sw = new SpinWait (); while (!IsCompleted) sw.SpinOnce (); return false; } Status = TaskStatus.Running; this.value = result; Thread.MemoryBarrier (); Finish (); return true; } #if NET_4_5 public Task ContinueWith (Action, object> continuationAction, object state) { return ContinueWith (continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current); } public Task ContinueWith (Action, object> continuationAction, object state, CancellationToken cancellationToken) { return ContinueWith (continuationAction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current); } public Task ContinueWith (Action, object> continuationAction, object state, TaskContinuationOptions continuationOptions) { return ContinueWith (continuationAction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current); } public Task ContinueWith (Action, object> continuationAction, object state, TaskScheduler scheduler) { return ContinueWith (continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler); } public Task ContinueWith (Action, object> continuationAction, object state, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { if (continuationAction == null) throw new ArgumentNullException ("continuationAction"); if (scheduler == null) throw new ArgumentNullException ("scheduler"); var t = new Task (TaskActionInvoker.Create (continuationAction), state, cancellationToken, GetCreationOptions (continuationOptions), null, this); ContinueWithCore (t, continuationOptions, scheduler); return t; } public Task ContinueWith (Func, object, TNewResult> continuationFunction, object state) { return ContinueWith (continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current); } public Task ContinueWith (Func, object, TNewResult> continuationFunction, object state, CancellationToken cancellationToken) { return ContinueWith (continuationFunction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current); } public Task ContinueWith (Func, object, TNewResult> continuationFunction, object state, TaskContinuationOptions continuationOptions) { return ContinueWith (continuationFunction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current); } public Task ContinueWith (Func, object, TNewResult> continuationFunction, object state, TaskScheduler scheduler) { return ContinueWith (continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler); } public Task ContinueWith (Func, object, TNewResult> continuationFunction, object state, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { if (continuationFunction == null) throw new ArgumentNullException ("continuationFunction"); if (scheduler == null) throw new ArgumentNullException ("scheduler"); var t = new Task (TaskActionInvoker.Create (continuationFunction), state, cancellationToken, GetCreationOptions (continuationOptions), null, this); ContinueWithCore (t, continuationOptions, scheduler); return t; } public new ConfiguredTaskAwaitable ConfigureAwait (bool continueOnCapturedContext) { return new ConfiguredTaskAwaitable (this, continueOnCapturedContext); } public new TaskAwaiter GetAwaiter () { return new TaskAwaiter (this); } #endif } } #endif