You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
5.6 KiB
224 lines
5.6 KiB
3 years ago
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
|
||
|
namespace ET
|
||
|
{
|
||
|
public static class ETTaskHelper
|
||
|
{
|
||
|
private class CoroutineBlocker
|
||
|
{
|
||
|
private int count;
|
||
|
|
||
|
private List<ETTask> tcss = new List<ETTask>();
|
||
|
|
||
|
public CoroutineBlocker(int count)
|
||
|
{
|
||
|
this.count = count;
|
||
|
}
|
||
|
|
||
|
public async ETTask WaitAsync()
|
||
|
{
|
||
|
--this.count;
|
||
|
if (this.count < 0)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
if (this.count == 0)
|
||
|
{
|
||
|
List<ETTask> t = this.tcss;
|
||
|
this.tcss = null;
|
||
|
foreach (ETTask ttcs in t)
|
||
|
{
|
||
|
ttcs.SetResult();
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
ETTask tcs = ETTask.Create(true);
|
||
|
|
||
|
tcss.Add(tcs);
|
||
|
await tcs;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static async ETTask<bool> WaitAny<T>(ETTask<T>[] tasks, ETCancellationToken cancellationToken = null)
|
||
|
{
|
||
|
if (tasks.Length == 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
CoroutineBlocker coroutineBlocker = new CoroutineBlocker(2);
|
||
|
|
||
|
foreach (ETTask<T> task in tasks)
|
||
|
{
|
||
|
RunOneTask(task).Coroutine();
|
||
|
}
|
||
|
|
||
|
async ETVoid RunOneTask(ETTask<T> task)
|
||
|
{
|
||
|
await task;
|
||
|
await coroutineBlocker.WaitAsync();
|
||
|
}
|
||
|
|
||
|
await coroutineBlocker.WaitAsync();
|
||
|
|
||
|
if (cancellationToken == null)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return !cancellationToken.IsCancel();
|
||
|
}
|
||
|
|
||
|
public static async ETTask<bool> WaitAny(ETTask[] tasks, ETCancellationToken cancellationToken = null)
|
||
|
{
|
||
|
if (tasks.Length == 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
CoroutineBlocker coroutineBlocker = new CoroutineBlocker(2);
|
||
|
|
||
|
foreach (ETTask task in tasks)
|
||
|
{
|
||
|
RunOneTask(task).Coroutine();
|
||
|
}
|
||
|
|
||
|
async ETVoid RunOneTask(ETTask task)
|
||
|
{
|
||
|
await task;
|
||
|
await coroutineBlocker.WaitAsync();
|
||
|
}
|
||
|
|
||
|
await coroutineBlocker.WaitAsync();
|
||
|
|
||
|
if (cancellationToken == null)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return !cancellationToken.IsCancel();
|
||
|
}
|
||
|
|
||
|
public static async ETTask<bool> WaitAll<T>(ETTask<T>[] tasks, ETCancellationToken cancellationToken = null)
|
||
|
{
|
||
|
if (tasks.Length == 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
CoroutineBlocker coroutineBlocker = new CoroutineBlocker(tasks.Length + 1);
|
||
|
|
||
|
foreach (ETTask<T> task in tasks)
|
||
|
{
|
||
|
RunOneTask(task).Coroutine();
|
||
|
}
|
||
|
|
||
|
async ETVoid RunOneTask(ETTask<T> task)
|
||
|
{
|
||
|
await task;
|
||
|
await coroutineBlocker.WaitAsync();
|
||
|
}
|
||
|
|
||
|
await coroutineBlocker.WaitAsync();
|
||
|
|
||
|
if (cancellationToken == null)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return !cancellationToken.IsCancel();
|
||
|
}
|
||
|
|
||
|
public static async ETTask<bool> WaitAll<T>(List<ETTask<T>> tasks, ETCancellationToken cancellationToken = null)
|
||
|
{
|
||
|
if (tasks.Count == 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
CoroutineBlocker coroutineBlocker = new CoroutineBlocker(tasks.Count + 1);
|
||
|
|
||
|
foreach (ETTask<T> task in tasks)
|
||
|
{
|
||
|
RunOneTask(task).Coroutine();
|
||
|
}
|
||
|
|
||
|
async ETVoid RunOneTask(ETTask<T> task)
|
||
|
{
|
||
|
await task;
|
||
|
await coroutineBlocker.WaitAsync();
|
||
|
}
|
||
|
|
||
|
await coroutineBlocker.WaitAsync();
|
||
|
|
||
|
if (cancellationToken == null)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return !cancellationToken.IsCancel();
|
||
|
}
|
||
|
|
||
|
public static async ETTask<bool> WaitAll(ETTask[] tasks, ETCancellationToken cancellationToken = null)
|
||
|
{
|
||
|
if (tasks.Length == 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
CoroutineBlocker coroutineBlocker = new CoroutineBlocker(tasks.Length + 1);
|
||
|
|
||
|
foreach (ETTask task in tasks)
|
||
|
{
|
||
|
RunOneTask(task).Coroutine();
|
||
|
}
|
||
|
|
||
|
await coroutineBlocker.WaitAsync();
|
||
|
|
||
|
async ETVoid RunOneTask(ETTask task)
|
||
|
{
|
||
|
await task;
|
||
|
await coroutineBlocker.WaitAsync();
|
||
|
}
|
||
|
|
||
|
if (cancellationToken == null)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return !cancellationToken.IsCancel();
|
||
|
}
|
||
|
|
||
|
public static async ETTask<bool> WaitAll(List<ETTask> tasks, ETCancellationToken cancellationToken = null)
|
||
|
{
|
||
|
if (tasks.Count == 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
CoroutineBlocker coroutineBlocker = new CoroutineBlocker(tasks.Count + 1);
|
||
|
|
||
|
foreach (ETTask task in tasks)
|
||
|
{
|
||
|
RunOneTask(task).Coroutine();
|
||
|
}
|
||
|
|
||
|
await coroutineBlocker.WaitAsync();
|
||
|
|
||
|
async ETVoid RunOneTask(ETTask task)
|
||
|
{
|
||
|
await task;
|
||
|
await coroutineBlocker.WaitAsync();
|
||
|
}
|
||
|
|
||
|
if (cancellationToken == null)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return !cancellationToken.IsCancel();
|
||
|
}
|
||
|
}
|
||
|
}
|