我有一个使用MVVM设计属性的WPF应用程序。有一个很长的运行过程来填充网格,我想显示一个忙碌的光标。我有部分改变光标工作。我遇到的问题是光标绑定到名为IsBusy的bool。当调用运行一段时间的方法时,我将IsBusy设置为true,当方法完成时,我将其设置为false。
public void LongProcedure(){
IsBusy=true;
... long running code here
IsBusy=false;
}
`
我知道光标绑定到IsBusy是有效的,因为我用另一个执行
的过程测试了它IsBusy=!IsBusy;
这会切换光标。我遇到的问题是,当方法中的代码运行时,视图似乎没有刷新。在我将IsBusy设置为true后,有没有办法强制视图重新设置?
答案 0 :(得分:3)
在每个窗口化应用程序中,都有一个专门用于处理应用程序可视化表示的线程。这个帖子是the UI thread。当您的代码响应窗口事件(例如,Loaded事件或用户单击按钮)而运行时,它将在此UI线程上运行。当您的代码运行时,UI线程将占用执行您的工作,并且无法更新窗口的可视化表示。在极端情况下(即,您的工作需要花费大量时间才能完成),您的窗口将显示为已锁定。
如果您使用UI线程执行长时间运行的工作,那么您没有正确执行。您应该使用async-await,或使用Task.Run()
以便在后台线程上执行 。
如果LongProcedure()
是IO绑定的(比如从某处等待数据),那么你应该使用async-await。如果它受CPU限制(大量数据处理/计算),那么您应该使用Task.Run()
异步AWAIT:
public async Task LongProcedure()
{
IsBusy = true;
await GetDataFromSomewhereAsync();
IsBusy = false;
}
public async void CallingMethod()
{
......
await LongProcedure();
}
Task.Run:
public void LongProcedure()
{
IsBusy = true;
... // long running code here
IsBusy = false;
}
public async void CallingMethod()
{
......
await Task.Run((Action) LongProcedure);
}
请注意,无法直接从后台线程更新UI。通常,您需要首先将更新代码编组到UI线程上。有许多不同的方法,它取决于您使用的Windows应用程序类型,例如windows forms,WPF等。