C# 取消执行并在方法重新输入时重新执行
我看到有人问过类似的问题,但它似乎不太适合我的情况 我们有一个可以执行请求的UI,如果用户希望再次执行请求(使用不同的查询参数),我们希望放弃初始请求,忽略其响应,只使用最新的请求响应 目前我有:C# 取消执行并在方法重新输入时重新执行,c#,.net,task-parallel-library,async-await,C#,.net,Task Parallel Library,Async Await,我看到有人问过类似的问题,但它似乎不太适合我的情况 我们有一个可以执行请求的UI,如果用户希望再次执行请求(使用不同的查询参数),我们希望放弃初始请求,忽略其响应,只使用最新的请求响应 目前我有: private readonly IDataService _dataService; private readonly MainViewModel _mainViewModel; private CancellationTokenSource _cancellationTokenSource;
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 **
}
}
这似乎运行良好,我有一个很好的响应用户界面,但我有一个与我有关的场景:
- 卢西安·维希克
ViewModel
)
为了确保不会发生这种情况,在您要更新UI/模型之前,无论您在哪里进行更新,都要使用带有相应令牌的ThrowIfCancellationRequested
。那么,任务的最新实例是否在前一个旧实例之前完成就无关紧要了。较旧的任务将在有机会执行任何有害操作之前通过取消安装请求到达点,因此您不必等待较旧的任务:
public异步void Execute()
{
if(_cancellationTokenSource!=null)
{
_cancellationTokenSource.Cancel();
}
_cancellationTokenSource=新的cancellationTokenSource();
var token=\u cancellationTokenSource.token。
尝试
{
字符串dataItem=await\u dataService.GetDataAsync(
_mainViewModel.Request,
代币);
token.ThrowIfCancellationRequested();
_mainViewModel.Data.Add(数据项);
}
捕获(操作取消异常)
{
//清理**关注区域**
}
}
另一个问题是,在上一个任务失败时,除了TaskCanceledException
之外,还需要做什么。新任务完成后也可能发生这种情况。由您决定是否忽略此异常、重新抛出它或执行任何其他操作:
试试看
{
字符串dataItem=await\u dataService.GetDataAsync(
_mainViewModel.Request,
代币);
token.ThrowIfCancellationRequested();
_mainViewModel.Data.Add(数据项);
}
捕获(例外情况除外)
{
如果(ex is OperationCanceledException)
返回
如果(!token.IsCancellationRequested)
{
//在请求取消之前抛出,
//报告并重新抛出
MessageBox.Show(例如Message);
投掷;
}
//否则,记录并忽略
}
为什么整理会覆盖结果?在通话前清除结果。你不想同时处理OperationCanceledException吗?@Blam,你当然是对的,我最初误解了你。是的,OperationCanceledException
应该在任何地方使用,而不是taskCanceledException
。我在复制OP的代码时忽略了这一点。好吧,这是吹毛求疵,我会有一个catch(OperationCanceledException-Ex)@Blam,不用担心,但是为什么catch(OperationCanceledException-Ex){}
中没有主体的时候没有主体呢?这两种方式都没有主体。为什么捕获作为一般异常,然后测试OperationCanceledException?