【问题标题】:EF 5: How to cancel a longrunning query in a async TaskEF 5:如何在异步任务中取消长时间运行的查询
【发布时间】:2013-08-05 13:24:43
【问题描述】:

在我的应用程序中,我有多个选项卡,使用 Entity Framework 5 显示来自数据库的数据。

当我在选项卡之间切换时,我开始通过任务自动加载数据,因为我不希望 GUI 变得无响应(此任务大约需要 5-10 秒):

public async void LoadData()
{
    [...]

    await Task.Run(
        () =>
            {
                Measurements = DataContext.Measurements
                                  .Where(m => m.MeasureDate = DateTime.Today)
                                  .ToList();
            });

    [...]
}

但是当任务运行时,用户仍然可以切换到另一个选项卡,如果他这样做了,我想取消 EF 查询和/或任务。

最好的方法是什么?

【问题讨论】:

    标签: c# .net wpf entity-framework


    【解决方案1】:

    在 EF5 中,无法取消查询,因为它不接受 CancellationToken。你可以在这里阅读更多信息:entity framework cancel long running query

    但是,EF6 确实支持它。

    它具有所有方法的异步版本。所以ToList() 可以改为ToListAsync() 用于长时间运行的查询,它确实支持CancellationToken

    【讨论】:

    • 关于 EF6 何时发布有任何消息吗?我考虑过使用它很多次,因为我们的软件将在 9 月/ 10 月发布,我希望在那之前能稳定发布。
    • @Staeff:据说今年年底会发布!
    【解决方案2】:
    // ***Declare a System.Threading.CancellationTokenSource.
    CancellationTokenSource cts;
    public async void LoadData()
    {
       // ***Instantiate the CancellationTokenSource.
        cts = new CancellationTokenSource();
        await Task.Run(
            () =>
                {
                    Measurements = DataContext.Measurements
                                      .Where(m => m.MeasureDate = DateTime.Today)
                                      .ToList();
                }, cts);
    
    }
    
        //I dont know what front end you using but in WPF for example on the tab event
        <TabControl SelectionChanged="OnSelectionChanged" ... />
    
    private void OnSelectionChanged(Object sender, SelectionChangedEventArgs args)
    {
        TabItem item = sender as TabItem; //The sender is a type of TabItem...
    
        if (item != null)
        {
             if (cts != null)
             {
                //This cancels the current long Running task.
                cts.Cancel();
    
                //call for next tab with filter LoadData(filter);
             }
        }
    }
    

    我个人的看法是。执行此操作的最佳方法是尽可能提前加载选项卡的所有数据。然后渲染视图。因此,当您在选项卡之间单击时,数据已经加载。加上调用数据库的成本只影响你一次。而不是每次单击选项卡时都往返于数据库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-05
      • 1970-01-01
      • 2016-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多