第一次执行时,实体框架ToListAsync阻止ui

时间:2015-06-23 09:07:48

标签: c# wpf entity-framework

我有一个下一个视图模型:

public class ExampleViewModel : INotifyPropertyChanged
{
    public ICommand TestCommand { get; private set; }

    private IEnumerable<Databases.Main.Models.Robot> _testCollection;
    public IEnumerable<Databases.Main.Models.Robot> TestCollection
    {
        get { return _testCollection; }
        private set
        {
            _testCollection = value;
            var handler = Volatile.Read(ref PropertyChanged);
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs("TestCollection"));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public ExampleViewModel()
    {
        TestCommand = DelegateCommand.FromAsyncHandler(Test);
    }

    private async Task Test()
    {
        using (var context = new AtonMainDbContext())
        {
            TestCollection = await context.Set<Databases.Main.Models.Robot>().ToListAsync();
        }
    }
}

下一个xaml:

            <Button Content="Refresh"
                    Command="{Binding TestCommand}"/>
            <ListBox ItemsSource="{Binding TestCollection}"
                     DisplayMemberPath="Name"/>

当我执行TestCommand时,UI会在第一次执行时冻结几秒钟。我不喜欢它。 但是,如果我不使用ToListAsync并使用Task包装ToList方法,那么一切正常,UI不会冻结。

    private async Task Test()
    {
        using (var context = new AtonMainDbContext())
        {
            TestCollection = await Task.Run(() => context.Set<Databases.Main.Models.Robot>().ToList());
        }
    }

为什么会这样?

1 个答案:

答案 0 :(得分:2)

您正在某处调用ResultWait

这是一个classic ASP.NET deadlock.不要阻止。 Task.Run是一种变通方法,因为它会删除其正文中的同步上下文。

相关问题