// // 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; 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 (); static readonly Action emptyAction = delegate (object o) {}; TResult value; Func function; Func simpleFunction; object state; [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 (emptyAction, null, cancellationToken, creationOptions) { if (function == null) throw new ArgumentNullException ("function"); this.simpleFunction = function; this.state = null; } 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 (emptyAction, state, cancellationToken, creationOptions) { if (function == null) throw new ArgumentNullException ("function"); this.function = function; this.state = state; } internal Task (Func function, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, Task parent) : base (emptyAction, state, cancellationToken, creationOptions, parent) { this.function = function; this.state = state; } internal override void InnerInvoke () { if (function != null) value = function (state); else if (simpleFunction != null) value = simpleFunction (); function = null; simpleFunction = null; state = null; } 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 (l => continuationAction ((Task)l), this, cancellationToken, GetCreationOptions (continuationOptions), 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"); Task t = new Task ((o) => continuationFunction ((Task)o), this, cancellationToken, GetCreationOptions (continuationOptions), this); ContinueWithCore (t, continuationOptions, scheduler); return t; } #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 (l => continuationAction (this, l), state, cancellationToken, GetCreationOptions (continuationOptions), 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 (l => continuationFunction (this, l), state, cancellationToken, GetCreationOptions (continuationOptions), 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