如果您尝试在异步上下文中对 CommunityTookit.Mvvm 包中标有 ObservableProperty 的属性之一运行更新,您将收到以下异常:
System.Runtime.Interop.COMException
示例:
private void MyButton_ClikEvent(Sender s, Args args)
{
Task.Run(async() =>
{
await AsyncTask();
ViewModel.Property = x; // This will throw an exception.
});
}
这种情况发生在 WinUI 上,因为异步上下文将在与 UI 线程不同的线程中运行,并且无法与 UIThread 同步,从而导致 COMException。
您可以通过将异步代码移动到视图模型并将其保留在任务中以使用中继命令对其进行标记来获得解决方法:
// ViewModel.cs
[RelayCommand]
async Task MyAsyncCode()
{
await stuffAsync();
Property = x; // Update your properties here.
}
// Your page
private void MyButton_ClikEvent(Sender s, Args args)
{
ViewModel.MyAsyncCodeCommand.Execute(null); //This will let the ViewModel handle all the async calls.
}
如果您遵循这种方法,您将不会收到错误,并且生成的代码将负责与 UIThread 的同步部分。
这是根据 ComminutyTookit Repo 中发布的讨论编写的。我也把我的回复放在那里。