3 // TaskCompletionSource.cs
6 // Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
8 // Copyright (c) 2009 Jérémie "Garuma" Laval
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
11 // of this software and associated documentation files (the "Software"), to deal
12 // in the Software without restriction, including without limitation the rights
13 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 // copies of the Software, and to permit persons to whom the Software is
15 // furnished to do so, subject to the following conditions:
17 // The above copyright notice and this permission notice shall be included in
18 // all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30 namespace System.Threading.Tasks
32 public class TaskCompletionSource<TResult>
36 public TaskCompletionSource ()
38 source = new Task<TResult> (null);
41 public TaskCompletionSource (object state)
43 source = new Task<TResult> (null, state);
46 public TaskCompletionSource (TaskCreationOptions options)
48 source = new Task<TResult> (null, options);
51 public TaskCompletionSource (object state, TaskCreationOptions options)
53 source = new Task<TResult> (null, state, options);
56 public void SetCanceled ()
58 if (!ApplyOperation (TaskStatus.Canceled, () => { source.Cancel (); source.CancelReal (); }))
59 ThrowInvalidException ();
62 public void SetException (Exception e)
64 if (!ApplyOperation (TaskStatus.Faulted, () => source.Exception = e))
65 ThrowInvalidException ();
68 public void SetResult (TResult result)
70 if (!ApplyOperation (TaskStatus.RanToCompletion, () => source.Result = result))
71 ThrowInvalidException ();
74 void ThrowInvalidException ()
76 throw new InvalidOperationException ("The underlying Task is already in one of the three final states: RanToCompletion, Faulted, or Canceled.");
79 public bool TrySetCanceled ()
81 return ApplyOperation (TaskStatus.Canceled, () => { source.Cancel (); source.CancelReal (); });
84 public bool TrySetException (Exception e)
86 return ApplyOperation (TaskStatus.Faulted, () => source.Exception = e);
89 public bool TrySetResult (TResult result)
91 return ApplyOperation (TaskStatus.RanToCompletion, () => source.Result = result);
94 bool ApplyOperation (TaskStatus newStatus, Action action)
96 if (CheckInvalidState ())
101 source.Status = newStatus;
106 bool CheckInvalidState ()
108 return source.Status == TaskStatus.RanToCompletion ||
109 source.Status == TaskStatus.Faulted ||
110 source.Status == TaskStatus.Canceled;
114 public Task<TResult> Task {