gpt4 book ai didi

c# - 取消执行并在方法重新进入时重新执行

转载 作者:行者123 更新时间:2023-11-30 22:08:17 27 4
gpt4 key购买 nike

我看到有人问过类似的问题 here但它似乎不太适合我的场景。

我们有一个可以执行请求的 UI,如果用户想再次执行请求(使用不同的查询参数),我们想放弃初始请求,忽略它的响应,只使用最新的请求响应。

目前我有:

private readonly IDataService _dataService;
private readonly MainViewModel _mainViewModel;

private CancellationTokenSource _cancellationTokenSource;

//Constructor omitted for brevity

public async void Execute()
{
if (_cancellationTokenSource != null)
{
_cancellationTokenSource.Cancel();
}

_cancellationTokenSource = new CancellationTokenSource();

try
{
string dataItem = await _dataService.GetDataAsync(_mainViewModel.Request, _cancellationTokenSource.Token);
_mainViewModel.Data.Add(dataItem);
}
catch (TaskCanceledException)
{
//Tidy up ** area of concern **
}
}

这似乎运行良好,我有一个漂亮且响应迅速的用户界面,但我有一个与我有关的场景:

  1. 用户提出请求
  2. 用户提出新的请求,取消了原来的请求
  3. 新请求在原始取消请求抛出异常之前返回,并用当前所需的数据填充 UI
  4. 抛出异常并进行清理,覆盖新的请求输出

这可能非常罕见,但我认为这是可能的,除非我对此的理解是错误的。

有什么方法可以确保如果通过取消 token 请求取消任务并启动新任务,则取消会在新任务启动/返回执行之前发生,而不会阻塞 UI 线程?

任何能加深我对此理解的阅读都将不胜感激。

最佳答案

Is there any way to ensure that if a Task is cancelled via a cancellation token request and a new Task is started the cancellation happens before the new task is started/returns execution without blocking the UI thread?

Any reading to expand my understanding on this would be most appreciated.

首先,应要求提供一些相关阅读和问题:

如果我对你的问题的理解正确,你主要担心的是同一任务的前一个实例可能会用过时的结果更新 UI(或 ViewModel),一旦它已完成。

为确保不会发生这种情况,请使用带有相应 token 的ThrowIfCancellationRequested 您要更新 UI/模型之前,到处 你这样做。那么,任务的最新实例是否在前一个较早的实例之前完成就无关紧要了。旧任务将到达 ThrowIfCancellationRequested之前 它可能有机会做任何有害的事情,因此您不必 await任务:

public async void Execute()
{
if (_cancellationTokenSource != null)
{
_cancellationTokenSource.Cancel();
}

_cancellationTokenSource = new CancellationTokenSource();
var token = _cancellationTokenSource.Token.

try
{
string dataItem = await _dataService.GetDataAsync(
_mainViewModel.Request,
token);

token.ThrowIfCancellationRequested();

_mainViewModel.Data.Add(dataItem);
}
catch (OperationCanceledException)
{
//Tidy up ** area of concern **
}
}

一个不同的问题是在前一个任务因 TaskCanceledException 以外的任何原因而失败的情况下该怎么办。这也可能在较新的任务完成后发生。由您决定是忽略此异常、重新抛出它还是执行任何其他操作:

try
{
string dataItem = await _dataService.GetDataAsync(
_mainViewModel.Request,
token);

token.ThrowIfCancellationRequested();

_mainViewModel.Data.Add(dataItem);
}
catch (Exception ex)
{
if (ex is OperationCanceledException)
return

if (!token.IsCancellationRequested)
{
// thrown before the cancellation has been requested,
// report and re-throw
MessageBox.Show(ex.Message);
throw;
}

// otherwise, log and ignore
}

关于c# - 取消执行并在方法重新进入时重新执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22425321/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com