为什么"等待LoadAsync()" "等待Task.Run(()=> Load())"冻结用户界面。才不是?

时间:2014-11-20 22:54:51

标签: .net wpf entity-framework async-await

我正在关注如何将EntityFramework与WPF结合使用a walkthrough。我决定玩async / await,因为我之前从未真正有机会使用它(我们刚从VS2010 / .NET 4.0转移到VS2013 / .NET 4.5)。让保存按钮处理程序变为异步是轻而易举的,并且在等待SaveChangesAsync()时,UI仍然保持响应(我可以拖动窗口)。然而,在窗口加载处理程序中,我遇到了一个小问题。

    private async void Window_Loaded(object sender, RoutedEventArgs e)
    {
        EnterBusyState();
        var categoryViewSource = (CollectionViewSource)FindResource("categoryViewSource");
        _context = await Task.Run(() => new Context());
        await Task.Run(() => _context.Categories.Load());
        //await _context.Categories.LoadAsync();
        categoryViewSource.Source = _context.Categories.Local;
        LeaveBusyState();
    }

当我使用加载_context.Categories的第一种方式时,UI仍然保持响应,但当我用下面的注释掉的行代替时,UI会在实体加载时冻结一小段时间。有没有人解释为什么前者有效而后者无效呢?这不是什么大不了的事情,只是在第二行不行时,至少根据我迄今为止研究过的关于async / await的情况,这应该是不行的。

1 个答案:

答案 0 :(得分:6)

即使方法以*Async结尾或返回任务并不意味着它完全是异步或异步...

示例:

public Task FooAsync()
{
    Thread.Sleep(10000); // This blocks the calling thread
    return Task.FromResult(true);
}

用法(看起来像异步调用):

await FooAsync();

示例方法完全同步,即使它返回一个任务......您需要检查LoadAsync的实现并确保没有任何阻塞。

当使用Task.Run时,lambda中的所有内容都在线程池上执行异步...(或者至少不阻塞调用线程)。

相关问题