gpt4 book ai didi

c# - 在另一个 AppDomain 中调用 Await 时没有 SynchronizationContext

转载 作者:行者123 更新时间:2023-11-30 18:20:54 25 4
gpt4 key购买 nike

我已经成功地构建了一个插件机制,我可以在一个单独的 AppDomain 中创建 UI 控件,并将它们作为表单的一部分显示在主 AppDomain 中。

这些 UI 控件会自行加载数据,因此当我打开一个表单时,会创建大约 10 个不同的插件,每个插件都需要加载其数据。

同样,如果我同步执行这一切都很好,但我想在每个插件中使用异步/等待模式。我的刷新方法如下所示:

protected async void RefreshData()
{
_data = await LoadAsync(_taskId); <= UI Thread :)
OnDataChanged(); <= Worker Thread :(
}

现在问题开始了。当我进入这个方法时,我在主 UI 线程上。但是当等待结束时,我在工作线程上,所以我在更新控件的 OnDataChanged() 方法中得到一个跨线程异常。

await 应该默认使用 SynchronizationContext.Current 来延续它,但因为我在另一个 AppDomain 中,所以它恰好为 NULL。

所以我的问题是。如何配置 await 以在当前线程(即 UI 线程)上继续?

我知道我可以获取一个控件并执行 Invoke() 但我也在使用 MVVM 模式,这是在 View 模型中,所以我无权访问那里的任何控件,所有 View 模型 -> View 通信都是通过数据绑定(bind)完成。

最佳答案

我终于想出了如何在没有控件句柄的情况下从单独的 AppDomain 返回到 UI-Thread。

因为我的 View 模型总是在 UI 线程上实例化,所以我只需获取当前的调度程序:

_dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher

现在,在我的 RefreshData 方法中,我所要做的就是分派(dispatch)等待后要执行的操作。

protected async void RefreshData()
{
_data = await LoadAsync(_taskId); <= UI Thread :)
_dispatcher.Invoke(() => OnDataChanged()); <= UI Thread :)
}

这当然可以通过封装调度程序等变得更花哨。

这个想法实际上来自:MVVM Light Toolkit

关于c# - 在另一个 AppDomain 中调用 Await 时没有 SynchronizationContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36627061/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com