city-generation/Game/Assets/Scripts/Utils/Task.cs

92 lines
2.2 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace TransportGame.Utils
{
public class Task
{
public bool? Success { get; private set; }
private Exception thrownException;
private Action action;
private Thread thread;
private Task()
{
}
private static void RunAsync_ActionThread(object info)
{
Task taskInfo = (Task)info;
try
{
taskInfo.action();
taskInfo.Success = true;
}
catch (Exception ex)
{
taskInfo.thrownException = ex;
taskInfo.Success = false;
}
}
public static Task RunAsync(Action action)
{
// Set up task info object
Task taskInfo = new Task();
taskInfo.action = action;
taskInfo.thread = new Thread(RunAsync_ActionThread);
// Start thread
taskInfo.thread.Start(taskInfo);
// Return task info
return taskInfo;
}
public static IEnumerable Await(Action action)
{
return Task.RunAsync(action).Await();
}
public IEnumerable Await()
{
// Wait for thread to finish
while (thread.ThreadState == ThreadState.Running)
yield return null;
thread.Join();
// Rethrow exception
if (Success.HasValue && !Success.Value)
throw new Exception("Task failed", thrownException);
}
public static IEnumerable InParallel(params IEnumerable[] funcs)
{
// Obtain iterators
var iterators = funcs.Select(enumerable => enumerable.GetEnumerator()).ToArray();
// Execute a slice of each
bool stop;
do
{
stop = true;
foreach (var it in iterators)
if (it.MoveNext())
{
yield return it.Current;
stop = false;
}
} while (!stop);
}
}
}