Files
better-genshin-impact/BetterGenshinImpact/GameTask/TaskRunner.cs
辉鸭蛋 5a0f7226ed update ISoloTask
更新 Start 方法以接受 CancellationTokenSource 参数

这些更改主要是为了使 `Start` 方法能够接受 `CancellationTokenSource` 参数,从而更好地控制任务的取消操作。通过传递 `CancellationTokenSource`,可以在需要时取消正在运行的任务,提高了代码的灵活性和可控性。

具体更改包括:
- 将 `Start` 方法的签名从无参数更改为接受 `CancellationTokenSource` 参数。
- 在多个任务类(如 `AutoDomainTask.cs`、`AutoFightTask.cs`、`AutoGeniusInvokationTask.cs`、`AutoMusicGameTask.cs`、`AutoWoodTask.cs`)中,更新 `Start` 方法以接受并使用传入的 `CancellationTokenSource`。
- 在 `Duel.cs` 中,更新 `RunAsync` 和 `Run` 方法的参数以接受 `CancellationTokenSource`,并将 `Cts` 赋值为传入的 `cts`。
- 在 `ISoloTask.cs` 接口中,更新 `Start` 方法的签名以接受 `CancellationTokenSource` 参数。
- 在 `TaskRunner.cs` 中,调用 `soloTask.Start` 时传入 `CancellationContext.Instance.Cts` 作为参数。
2024-09-23 00:04:09 +08:00

178 lines
5.9 KiB
C#

using BetterGenshinImpact.Core.Script;
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception;
using BetterGenshinImpact.GameTask.Model.Enum;
using BetterGenshinImpact.View;
using BetterGenshinImpact.View.Drawable;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;
using BetterGenshinImpact.Helpers;
using Wpf.Ui.Violeta.Controls;
using static BetterGenshinImpact.GameTask.Common.TaskControl;
using BetterGenshinImpact.Core.Recorder;
namespace BetterGenshinImpact.GameTask;
/// <summary>
/// 用于以独立任务的方式执行任意方法
/// </summary>
public class TaskRunner
{
private readonly ILogger<TaskRunner> _logger = App.GetLogger<TaskRunner>();
private readonly DispatcherTimerOperationEnum _timerOperation = DispatcherTimerOperationEnum.None;
private readonly string _name = string.Empty;
public TaskRunner()
{
}
public TaskRunner(DispatcherTimerOperationEnum timerOperation)
{
_timerOperation = timerOperation;
}
/// <summary>
/// 加锁并独立运行任务
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
public async Task RunAsync(Func<Task> action)
{
// 加锁
var hasLock = await TaskSemaphore.WaitAsync(0);
if (!hasLock)
{
_logger.LogError("任务启动失败:当前存在正在运行中的独立任务,请不要重复执行任务!");
return;
}
try
{
_logger.LogInformation("→ {Text}", _name + "任务启动!");
// 初始化
Init();
// 发送运行任务通知
SendNotification();
CancellationContext.Instance.Set();
await action();
}
catch (NormalEndException e)
{
_logger.LogInformation("任务中断:{Msg}", e.Message);
SendNotification();
}
catch (Exception e)
{
_logger.LogError(e.Message);
_logger.LogDebug(e.StackTrace);
SendNotification();
}
finally
{
End();
_logger.LogInformation("→ {Text}", _name + "任务结束");
SendNotification();
CancellationContext.Instance.Clear();
// 释放锁
if (hasLock)
{
TaskSemaphore.Release();
}
}
}
public void FireAndForget(Func<Task> action)
{
Task.Run(() => RunAsync(action));
}
public async Task RunThreadAsync(Func<Task> action)
{
await Task.Run(() => RunAsync(action));
}
public async Task RunSoloTaskAsync(ISoloTask soloTask)
{
await Task.Run(() => RunAsync(async () => await soloTask.Start(CancellationContext.Instance.Cts)));
}
public void Init()
{
if (!TaskContext.Instance().IsInitialized)
{
UIDispatcherHelper.Invoke(() => { Toast.Warning("请先在启动页,启动截图器再使用本功能"); });
throw new NormalEndException("请先在启动页,启动截图器再使用本功能");
}
// 激活原神窗口
var maskWindow = MaskWindow.Instance();
SystemControl.ActivateWindow();
maskWindow.Invoke(maskWindow.Show);
if (_timerOperation == DispatcherTimerOperationEnum.UseSelfCaptureImage)
{
Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待日志窗口被激活
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.Stop);
}
else if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImage)
{
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.OnlyCacheCapture);
Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待缓存图像
}
else if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImageWithTrigger)
{
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待缓存图像
}
else if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty)
{
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
TaskTriggerDispatcher.Instance().ClearTriggers();
Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待缓存图像
}
}
public void End()
{
if (!TaskContext.Instance().IsInitialized)
{
return;
}
VisionContext.Instance().DrawContent.ClearAll();
if (_timerOperation == DispatcherTimerOperationEnum.UseSelfCaptureImage)
{
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.Start);
}
else if (_timerOperation is DispatcherTimerOperationEnum.UseCacheImage or DispatcherTimerOperationEnum.UseCacheImageWithTrigger or DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty)
{
// 还原到原来的模式
if (TaskContext.Instance().Config.CommonConfig.ScreenshotEnabled || TaskContext.Instance().Config.MacroConfig.CombatMacroEnabled)
{
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
}
else
{
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.NormalTrigger);
}
if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty)
{
TaskTriggerDispatcher.Instance().SetTriggers(GameTaskManager.LoadInitialTriggers());
}
}
}
public void SendNotification()
{
}
}