#if NET_4_0 // Future.cs // // Copyright (c) 2008 Jérémie "Garuma" Laval // // 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. // // using System; namespace System.Threading.Tasks { public static class Future { public static Future StartNew() { return StartNew(null, TaskManager.Current, TaskCreationOptions.None); } public static Future StartNew(Func function) { return StartNew(function, TaskManager.Current, TaskCreationOptions.None); } public static Future StartNew(Func function, TaskCreationOptions options) { return StartNew(function, TaskManager.Current, options); } public static Future StartNew(Func function, TaskManager tm) { return StartNew(function, tm, TaskCreationOptions.None); } public static Future StartNew(Func function, TaskManager tm, TaskCreationOptions options) { Future future = new Future(tm, function, options, true); return future; } } public sealed class Future: Task { T value; int alreadySet; Action func; public T Value { get { if (func != null) Wait(); return value; } set { int result = Interlocked.Exchange(ref alreadySet, 1); if (result == 1) throw new Exception("Value has already been set for this Future or you can't manually set it"); this.value = value; } } internal Future(TaskManager tm, Func f, TaskCreationOptions options): this(tm, f, options, false) { } internal Future(TaskManager tm, Func f, TaskCreationOptions options, bool scheduleNow): base(tm, null, null, options) { if (f != null) { // Block manual set alreadySet = 1; func = delegate { value = f(); }; } else { func = EmptyFunc; } if (scheduleNow) Schedule(); } static void EmptyFunc() { } protected override void InnerInvoke () { func(); // Same reason as in Task.InnerInvoke func = null; } public static Future StartNew() { return StartNew(null, TaskManager.Current, TaskCreationOptions.None); } public static Future StartNew(Func function) { return StartNew(function, TaskManager.Current, TaskCreationOptions.None); } public static Future StartNew(Func function, TaskCreationOptions options) { return StartNew(function, TaskManager.Current, options); } public static Future StartNew(Func function, TaskManager tm) { return StartNew(function, tm, TaskCreationOptions.None); } public static Future StartNew(Func function, TaskManager tm, TaskCreationOptions options) { Future future = new Future(tm, function, options, true); return future; } public Task ContinueWith(Action> a) { return ContinueWith(a, TaskContinuationKind.OnAny, TaskCreationOptions.None); } public Task ContinueWith(Action> a, TaskContinuationKind kind) { return ContinueWith(a, kind, TaskCreationOptions.None); } public Task ContinueWith(Action> a, TaskContinuationKind kind, TaskCreationOptions option) { return ContinueWith(a, kind, option, false); } public Task ContinueWith(Action> a, TaskContinuationKind kind, TaskCreationOptions option, bool exSync) { Task continuation = new Task(TaskManager.Current, delegate { a(this); }, null, option); ContinueWithCore(continuation, kind, exSync); return continuation; } public Future ContinueWith(Func, U> a) { return ContinueWith(a, TaskContinuationKind.OnAny, TaskCreationOptions.None); } public Future ContinueWith(Func, U> a, TaskContinuationKind kind) { return ContinueWith(a, kind, TaskCreationOptions.None); } public Future ContinueWith(Func, U> a, TaskContinuationKind kind, TaskCreationOptions option) { return ContinueWith(a, kind, option, false); } public Future ContinueWith(Func, U> a, TaskContinuationKind kind, TaskCreationOptions option, bool exSync) { Future continuation = new Future(TaskManager.Current, delegate { return a(this); }, option, false); ContinueWithCore(continuation, kind, exSync); return continuation; } } } #endif