获取最后请求的异步结果并取消之前未完成的任务
Take the Last Requested Async Result and Cancelling Previous Unfinished Tasks
我有多个繁重的作业计算请求。这项工作可能需要不同的时间。通过使用 async
和 await
我想获取最后请求的结果并取消最终未完成的先前任务。
目前我正在使用 BackGroundWorker 设置作业 ID。我只使用了最后请求 ID 的结果。
我可以使用 async
await
重写代码吗?
private int backtestId;
private void PrepareStrategyCalculation()
{
backtestId = backtestManager.GetNextBacktestId();
strategy.BacktestId = backtestId;
backtestManager.StartBacktestWorker(strategy.Clone());
}
private void BacktestManager_StrategyBacktested(object sender, StrategyBacktestEventArgs e)
{
if (e.BacktestObject.Strategy.BacktestId != backtestId) return;
var calculatedStrategy = e.BacktestObject.Strategy;
...
}
编辑:
这是解决方案吗?
private int backtestId;
private async void PrepareStrategyCalculation()
{
backtestId = backtestManager.GetNextBacktestId();
strategy.BacktestId = backtestId;
var calculatedStrategy = await backtestManager.StartBacktestAsync(strategy.Clone());
if (calculatedStrategy.BacktestId != backtestId) return;
...
}
假设您的代码是 CPU-bound,那么 Task.Run
是 BackgroundWorker
的合适替代品。
您可以使用CancellationTokenSource
取消任务。因此,假设 StartBacktestAsync
是从单线程上下文调用的,例如 UI 线程:
private CancellationTokenSource _cts;
async Task StartBacktestAsync()
{
if (_cts != null)
_cts.Cancel();
_cts = new CancellationTokenSource();
try
{
var token = _cts.Token;
await Task.Run(() => Backtest(token));
}
catch (OperationCanceledException)
{
// Any special logic for a canceled operation.
}
}
void Backtest(CancellationToken token)
{
... // periodically call token.ThrowIfCancellationRequested();
}
我有多个繁重的作业计算请求。这项工作可能需要不同的时间。通过使用 async
和 await
我想获取最后请求的结果并取消最终未完成的先前任务。
目前我正在使用 BackGroundWorker 设置作业 ID。我只使用了最后请求 ID 的结果。
我可以使用 async
await
重写代码吗?
private int backtestId;
private void PrepareStrategyCalculation()
{
backtestId = backtestManager.GetNextBacktestId();
strategy.BacktestId = backtestId;
backtestManager.StartBacktestWorker(strategy.Clone());
}
private void BacktestManager_StrategyBacktested(object sender, StrategyBacktestEventArgs e)
{
if (e.BacktestObject.Strategy.BacktestId != backtestId) return;
var calculatedStrategy = e.BacktestObject.Strategy;
...
}
编辑:
这是解决方案吗?
private int backtestId;
private async void PrepareStrategyCalculation()
{
backtestId = backtestManager.GetNextBacktestId();
strategy.BacktestId = backtestId;
var calculatedStrategy = await backtestManager.StartBacktestAsync(strategy.Clone());
if (calculatedStrategy.BacktestId != backtestId) return;
...
}
假设您的代码是 CPU-bound,那么 Task.Run
是 BackgroundWorker
的合适替代品。
您可以使用CancellationTokenSource
取消任务。因此,假设 StartBacktestAsync
是从单线程上下文调用的,例如 UI 线程:
private CancellationTokenSource _cts;
async Task StartBacktestAsync()
{
if (_cts != null)
_cts.Cancel();
_cts = new CancellationTokenSource();
try
{
var token = _cts.Token;
await Task.Run(() => Backtest(token));
}
catch (OperationCanceledException)
{
// Any special logic for a canceled operation.
}
}
void Backtest(CancellationToken token)
{
... // periodically call token.ThrowIfCancellationRequested();
}