我有一个下一个视图模型:
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());
}
}
为什么会这样?
答案 0 :(得分:2)
您正在某处调用Result
或Wait
。
这是一个classic ASP.NET deadlock.不要阻止。 Task.Run
是一种变通方法,因为它会删除其正文中的同步上下文。