Miroslav Popov
Miroslav Popov

Reputation: 3383

Take the Last Requested Async Result and Cancelling Previous Unfinished Tasks

I have multiple heavy job calculation requests. The job may take different time. By using async and await I want to take the last requested result with canceling eventually unfinished previous tasks.

Currently I'm using BackGroundWorker with setting a job ID. I used only the the result with the last requested ID.

Can I rewrite the code with using 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;
    ...
}

EDIT:

Is this a solution?

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;

    ...
}

Upvotes: 0

Views: 246

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 456977

Assuming your code is CPU-bound, then Task.Run is a suitable substitute for BackgroundWorker.

You can use CancellationTokenSource to cancel tasks. So, something like this would work, assuming that StartBacktestAsync is called from a single-threaded context such as a UI thread:

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();
}

Upvotes: 2

Related Questions