【问题标题】:Cancel an async operation after the form has loaded?表单加载后取消异步操作?
【发布时间】:2016-05-12 21:55:38
【问题描述】:

我有不同的类(实现接口),其中一种方法是执行异步数据库搜索:

public async void SearchAsync(CancellationToken ct)
{
    await Task.Run(() => {Find(); }, ct);
}

private void Find()
{
    //do db search here...
}

当打开表单时,会执行后台异步搜索以加快用户输入,所以我要做的是:

protected override void OnShown(EventArgs e)
{
    base.OnShown(e);

    try
    {
        //Get list of items that will perform async search...
        //var results = ...

        //Do an async search
        Task task = Task.Factory.StartNew(() =>
            {
                foreach (var item in results)
                {
                    item.SearchAsync(cts.Token);
                }
            }, cts.Token);
    }
    catch (OperationCanceledException)
    { }
}

以防万一用户在任务仍在执行时关闭表单,我会这样做:

protected override void OnFormClosing(FormClosingEventArgs e)
{
    base.OnFormClosing(e);

    if (cts != null)
    {
        cts.Cancel();
    }
}

首先,以上是执行异步操作的正确方法吗?

其次,当我在任务仍未完成时关闭表单时,代码永远不会到达 OperationCancelException。莫非是上面的实现不正确?

【问题讨论】:

    标签: c# winforms asynchronous task-parallel-library


    【解决方案1】:

    有几点需要注意。首先,您使用的是"async over sync" 反模式,应该强烈避免。您还传递了CancellationToken,但实际上从未对其进行监控。如果您的方法是同步的,则在执行时您无法真正对其进行监控,最好的办法是在执行Search 的每次迭代之前监控CancellationToken

    public void Search()
    {
        Find();
    }
    
    protected override async void OnShown(EventArgs e)
    {
       base.OnShown(e);
    
       try
       {
           await Task.Run(() =>
           {
               foreach (var item in results)
               {
                   cts.Token.ThrowIfCancellationRequested();
                   item.Search();
               }
           }, cts.Token);
       }
       catch (OperationCanceledException)
       { }
    }
    

    然后你取消:

    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        base.OnFormClosing(e);
    
        if (cts != null)
        {
            cts.Cancel();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-16
      • 1970-01-01
      • 1970-01-01
      • 2011-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多