FiberTaskExtensions.cs
Go to the documentation of this file.
1 /*
2 
3 Author: Aaron Oneal, http://aarononeal.info
4 
5 Copyright (c) 2012 Spicy Pixel, http://spicypixel.com
6 
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14 
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 
26 */
27 using System;
28 using System.Collections;
29 using System.Threading;
30 using System.Threading.Tasks;
31 using SpicyPixel.Threading;
33 
34 namespace SpicyPixel.Threading.Tasks
35 {
39  public static class FiberTaskExtensions
40  {
53  public static Task ContinueWith (this Task task, IEnumerator coroutine)
54  {
55  return ContinueWith (task, coroutine, TaskContinuationOptions.None);
56  }
57 
73  public static Task ContinueWith (this Task task, IEnumerator coroutine, TaskContinuationOptions continuationOptions)
74  {
75  return ContinueWith (task, coroutine, CancellationToken.None, continuationOptions, TaskScheduler.Current);
76  }
77 
93  public static Task ContinueWith (this Task task, IEnumerator coroutine, CancellationToken cancellationToken)
94  {
95  return ContinueWith (task, coroutine, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
96  }
97 
113  public static Task ContinueWith (this Task task, IEnumerator coroutine, TaskScheduler scheduler)
114  {
115  return ContinueWith (task, coroutine, CancellationToken.None, TaskContinuationOptions.None, scheduler);
116  }
117 
139  public static Task ContinueWith (this Task task, IEnumerator coroutine, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
140  {
141  if (coroutine == null)
142  throw new ArgumentNullException ("coroutine");
143  if (scheduler == null)
144  throw new ArgumentNullException ("scheduler");
145  if (!(scheduler is FiberTaskScheduler))
146  throw new ArgumentException ("The scheduler for a YieldableTask must be a FiberTaskScheduler", "scheduler");
147 
148  // This creates a continuation that runs on the default scheduler (e.g. ThreadPool)
149  // where it's OK to wait on a child task to complete. The child task is scheduled
150  // on the given scheduler and attached to the parent.
151 
152  //var outerScheduler = TaskScheduler.Current;
153  //if(outerScheduler is MonoBehaviourTaskScheduler)
154  // outerScheduler = TaskScheduler.Default;
155 
156  var outerScheduler = TaskScheduler.Default;
157 
158  // The thread pool scheduler cannot be used in web scenarios. The outer scheduler
159  // must be the fiber scheduler.
160  //var outerScheduler = scheduler;
161 
162  return task.ContinueWith((Task antecedent) => {
163  var yieldableTask = new YieldableTask(coroutine, cancellationToken, TaskCreationOptions.AttachedToParent);
164  yieldableTask.Start(scheduler);
165  }, cancellationToken, continuationOptions, outerScheduler);
166  }
167 
180  public static Task ContinueWith (this Task task, FiberInstruction instruction)
181  {
182  return ContinueWith (task, instruction, TaskContinuationOptions.None);
183  }
184 
200  public static Task ContinueWith (this Task task, FiberInstruction instruction, TaskContinuationOptions continuationOptions)
201  {
202  return ContinueWith (task, instruction, CancellationToken.None, continuationOptions, TaskScheduler.Current);
203  }
204 
220  public static Task ContinueWith (this Task task, FiberInstruction instruction, CancellationToken cancellationToken)
221  {
222  return ContinueWith (task, instruction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
223  }
224 
240  public static Task ContinueWith (this Task task, FiberInstruction instruction, TaskScheduler scheduler)
241  {
242  return ContinueWith (task, instruction, CancellationToken.None, TaskContinuationOptions.None, scheduler);
243  }
244 
266  public static Task ContinueWith (this Task task, FiberInstruction instruction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
267  {
268  if (instruction == null)
269  throw new ArgumentNullException ("instruction");
270  if (scheduler == null)
271  throw new ArgumentNullException ("scheduler");
272  if (!(scheduler is FiberTaskScheduler))
273  throw new ArgumentException ("The scheduler for a YieldableTask must be a FiberTaskScheduler", "scheduler");
274 
275  // This creates a continuation that runs on the default scheduler (e.g. ThreadPool)
276  // where it's OK to wait on a child task to complete. The child task is scheduled
277  // on the given scheduler and attached to the parent.
278 
279  //var outerScheduler = TaskScheduler.Current;
280  //if(outerScheduler is MonoBehaviourTaskScheduler)
281  // outerScheduler = TaskScheduler.Default;
282 
283  var outerScheduler = TaskScheduler.Default;
284 
285  // The thread pool scheduler cannot be used in web scenarios. The outer scheduler
286  // must be the fiber scheduler.
287  //var outerScheduler = scheduler;
288 
289  return task.ContinueWith((Task antecedent) => {
290  var yieldableTask = new YieldableTask(instruction, cancellationToken, TaskCreationOptions.AttachedToParent);
291  yieldableTask.Start(scheduler);
292  }, cancellationToken, continuationOptions, outerScheduler);
293  }
294 
307  public static Task StartNew (this TaskFactory taskFactory, IEnumerator coroutine)
308  {
309  return StartNew (taskFactory, coroutine, taskFactory.CancellationToken, taskFactory.CreationOptions, taskFactory.Scheduler);
310  }
311 
327  public static Task StartNew (this TaskFactory taskFactory, IEnumerator coroutine, CancellationToken cancellationToken)
328  {
329  return StartNew (taskFactory, coroutine, cancellationToken, taskFactory.CreationOptions, taskFactory.Scheduler);
330  }
331 
347  public static Task StartNew (this TaskFactory taskFactory, IEnumerator coroutine, TaskCreationOptions creationOptions)
348  {
349  return StartNew (taskFactory, coroutine, taskFactory.CancellationToken, creationOptions, taskFactory.Scheduler);
350  }
351 
373  public static Task StartNew (this TaskFactory taskFactory, IEnumerator coroutine, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
374  {
375  var task = new YieldableTask (coroutine, cancellationToken, creationOptions);
376  task.Start (scheduler);
377  return task;
378  }
379 
392  public static Task StartNew (this TaskFactory taskFactory, FiberInstruction instruction)
393  {
394  return StartNew (taskFactory, instruction, taskFactory.CancellationToken, taskFactory.CreationOptions, taskFactory.Scheduler);
395  }
396 
412  public static Task StartNew (this TaskFactory taskFactory, FiberInstruction instruction, CancellationToken cancellationToken)
413  {
414  return StartNew (taskFactory, instruction, cancellationToken, taskFactory.CreationOptions, taskFactory.Scheduler);
415  }
416 
432  public static Task StartNew (this TaskFactory taskFactory, FiberInstruction instruction, TaskCreationOptions creationOptions)
433  {
434  return StartNew (taskFactory, instruction, taskFactory.CancellationToken, creationOptions, taskFactory.Scheduler);
435  }
436 
458  public static Task StartNew (this TaskFactory taskFactory, FiberInstruction instruction, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
459  {
460  var task = new YieldableTask (instruction, cancellationToken, creationOptions);
461  task.Start (scheduler);
462  return task;
463  }
464  }
465 }
466 
static Task ContinueWith(this Task task, IEnumerator coroutine, CancellationToken cancellationToken)
Continues the task with a coroutine.
Yieldable task for execution on a fiber.
static Task StartNew(this TaskFactory taskFactory, FiberInstruction instruction, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
Creates a new task and starts executing it.
static Task ContinueWith(this Task task, IEnumerator coroutine)
Continues the task with a coroutine.
static Task ContinueWith(this Task task, FiberInstruction instruction, CancellationToken cancellationToken)
Continues the task with a coroutine.
static Task ContinueWith(this Task task, FiberInstruction instruction, TaskScheduler scheduler)
Continues the task with a coroutine.
static Task ContinueWith(this Task task, IEnumerator coroutine, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
Continues the task with a coroutine.
static Task StartNew(this TaskFactory taskFactory, IEnumerator coroutine, CancellationToken cancellationToken)
Creates a new task and starts executing it.
static Task ContinueWith(this Task task, IEnumerator coroutine, TaskContinuationOptions continuationOptions)
Continues the task with a coroutine.
static Task StartNew(this TaskFactory taskFactory, FiberInstruction instruction)
Creates a new task and starts executing it.
Represents a fiber instruction to be processed by a FiberScheduler.
Extends the Task and TaskFactory classes with methods to support coroutines.
static Task StartNew(this TaskFactory taskFactory, IEnumerator coroutine, TaskCreationOptions creationOptions)
Creates a new task and starts executing it.
static Task ContinueWith(this Task task, FiberInstruction instruction, TaskContinuationOptions continuationOptions)
Continues the task with a coroutine.
static Task ContinueWith(this Task task, FiberInstruction instruction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
Continues the task with a coroutine.
static Task StartNew(this TaskFactory taskFactory, IEnumerator coroutine, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
Creates a new task and starts executing it.
static Task StartNew(this TaskFactory taskFactory, FiberInstruction instruction, CancellationToken cancellationToken)
Creates a new task and starts executing it.
static Task ContinueWith(this Task task, IEnumerator coroutine, TaskScheduler scheduler)
Continues the task with a coroutine.
static Task ContinueWith(this Task task, FiberInstruction instruction)
Continues the task with a coroutine.
static Task StartNew(this TaskFactory taskFactory, IEnumerator coroutine)
Creates a new task and starts executing it.
static Task StartNew(this TaskFactory taskFactory, FiberInstruction instruction, TaskCreationOptions creationOptions)
Creates a new task and starts executing it.
TaskScheduler that can execute fibers (yieldable coroutines).