Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 取消执行并在方法重新输入时重新执行_C#_.net_Task Parallel Library_Async Await - Fatal编程技术网

C# 取消执行并在方法重新输入时重新执行

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;

我看到有人问过类似的问题,但它似乎不太适合我的情况

我们有一个可以执行请求的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 **
    }
}
这似乎运行良好,我有一个很好的响应用户界面,但我有一个与我有关的场景:

  • 用户发出请求
  • 用户发出一个新请求,该请求将取消原始请求
  • 新请求在原始取消请求抛出异常(使用当前所需数据填充UI)之前返回
  • 引发异常,并在覆盖新请求输出时进行清理
  • 这可能非常罕见,但我可以将其视为一种可能性,除非我对此的理解是错误的

    是否有任何方法可以确保,如果通过取消令牌请求取消了任务,并且启动了新任务,则取消会在新任务启动之前发生/返回执行,而不会阻塞UI线程

    任何能扩大我对这方面理解的阅读都将不胜感激

    有没有办法确保如果某项任务通过 取消令牌请求,并在取消时启动新任务 在新任务启动之前发生/返回执行而不执行 阻止UI线程

    任何扩大我对这方面理解的阅读都是最重要的 谢谢

    首先,一些相关阅读和问题,如要求:

    • 卢西安·维希克
    如果我正确理解了您的问题,那么您主要担心的是,同一任务的前一个实例在完成后可能会用过时的结果更新UI(或
    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?