EF 5:如何在异步任务中取消长时间运行的查询

6
在我的应用程序中,我有多个选项卡,显示来自Entity Framework 5数据库的数据。当我在选项卡之间切换时,我会启动一个任务自动加载数据,因为我不想让GUI变得不响应(这个任务大约需要5-10秒):
public async void LoadData()
{
    [...]

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

    [...]
}

但是,尽管任务正在运行,用户仍然可以切换到另一个选项卡,如果这样做,我希望取消EF查询和/或任务。

如何最好地实现这一点?

2个回答

9
在EF5中,没有办法取消查询,因为它不接受CancellationToken。您可以在此处阅读更多信息:entity framework cancel long running query
然而,EF6支持它。它有所有方法的异步版本。因此,对于长时间运行的查询,ToList()可以改为ToListAsync(),并且它确实支持CancellationToken

有没有关于EF6何时发布的消息?我已经考虑过很多次使用它,因为我们的软件将在九月/十月发布,我希望在那之前能够有一个稳定的版本。 - Staeff
@Staeff:据说这将在今年年底发布! - TCM

0
// ***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);
         }
    }
}

我的个人观点是,如果可能的话,最好的方法是预先加载所有选项卡的数据,然后再呈现视图。这样,当您在选项卡之间切换时,数据已经被加载。而且只有一次调用数据库的成本会影响您。而不是每次单击选项卡时都要往返于数据库。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接