FunGame-Core/Service/TaskManager.cs
2023-09-28 20:10:17 +08:00

98 lines
3.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Milimoe.FunGame.Core.Interface.Base;
namespace Milimoe.FunGame.Core.Service
{
internal class TaskManager
{
/// <summary>
/// 开启一个任务调用返回对象的OnCompleted()方法可以执行后续操作,支持异步
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
internal static ITaskAwaiter NewTask(Action action) => new TaskAwaiter(action);
/// <summary>
/// 开启一个任务调用返回对象的OnCompleted()方法可以执行后续操作,支持异步
/// </summary>
/// <param name="function"></param>
/// <returns></returns>
internal static ITaskAwaiter NewTask(Func<Task> function) => new TaskAwaiter(function);
/// <summary>
/// 内部实现类
/// </summary>
private class TaskAwaiter : ITaskAwaiter
{
public bool IsCompleted => _IsCompleted;
public Exception Exception => _Exception;
private delegate void CompletedEvent();
private delegate void ErrorEvent(Exception e);
private event CompletedEvent? Completed;
private event ErrorEvent? Error;
private bool _IsCompleted = false;
private Exception _Exception = new();
internal TaskAwaiter(Action action) => _ = Worker(action);
internal TaskAwaiter(Func<Task> function) => _ = Worker(function);
/// <summary>
/// 返回ITaskAwaiter可以进一步调用方法<para/>
/// 但是意义不大前一个OnCompleted方法并不会等待下一个方法<para/>
/// 可以理解为并行广播<para/>
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
public ITaskAwaiter OnCompleted(Action action)
{
if (IsCompleted) action();
else Completed += new CompletedEvent(action);
return this;
}
/// <summary>
/// 在捕获到异常时将触发Error事件
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
public ITaskAwaiter OnError(Action<Exception> action)
{
Error += new ErrorEvent(action);
return this;
}
private async Task Worker(Action action)
{
try
{
await Task.Run(action);
_IsCompleted = true;
Completed?.Invoke();
}
catch (Exception e)
{
_Exception = e;
Error?.Invoke(e);
}
}
private async Task Worker(Func<Task> function)
{
try
{
await function();
_IsCompleted = true;
Completed?.Invoke();
}
catch (Exception e)
{
_Exception = e;
Error?.Invoke(e);
}
}
}
}
}