Avalonia MVVM异步方法为何阻塞用户界面?
Avalonia MVVM中异步方法阻塞UI的问题解决
你的代码里的问题很明确——你把长耗时操作DoSomethingForVeryLongTime()放到了UI线程中执行,哪怕用了Dispatcher.UIThread.InvokeAsync,本质还是在UI线程跑这个同步的长耗时方法,自然会卡住界面。
为什么会阻塞?
Dispatcher.UIThread.InvokeAsync的作用是让指定代码回到UI线程执行(比如更新UI元素时必须用它),但如果把耗时操作放进去,UI线程就会被这个操作占满,没法处理用户输入、界面刷新这些消息,导致无响应。
解决方案
情况1:耗时操作不需要访问UI元素(推荐)
直接把耗时操作放到后台线程执行,等操作完成后如果需要更新UI,再用Dispatcher回到UI线程:
private async Task OnRun() { // 用Task.Run把耗时操作丢到后台线程 await Task.Run(() => DoSomethingForVeryLongTime()); // 如果需要更新UI,再回到UI线程 await Dispatcher.UIThread.InvokeAsync(() => { // 这里写更新UI相关的逻辑,比如修改ViewModel的属性 }); }
情况2:耗时操作必须访问UI元素(不推荐,尽量避免)
如果没办法必须在UI线程执行,那得把长耗时操作拆成多个小步骤,每执行完一步就让出UI线程,让界面能响应:
private async Task OnRun() { await Dispatcher.UIThread.InvokeAsync(async () => { // 假设把长操作拆成多个小步骤 foreach (var step in GetLongRunningSteps()) { DoSmallPartOfWork(step); // 让出UI线程,让界面处理其他消息 await Task.Yield(); } }); }
内容的提问来源于stack exchange,提问作者user20510170
相关产品推荐
相关产品推荐

