windows 如何调度到主线程?

2mbi3lxu  于 2022-11-30  发布在  Windows
关注(0)|答案(2)|浏览(148)

我想用C#在.Net 6中的主线程(UI线程)内执行一些非主线程的代码。
我试过使用这个代码:

await Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher.RunAsync(
    Windows.UI.Core.CoreDispatcherPriority.Normal,
    () => { }
);

这不起作用,因为Windows.UI.Core.CoreWindow.GetForCurrentThread()返回null
我的第二次尝试是:

await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
    Windows.UI.Core.CoreDispatcherPriority.Normal,
    () => { }
);

这会失败,因为Windows.ApplicationModel.Core.CoreApplication.MainView会掷回System.InvalidOperationException
另一种说法应是:

await System.Windows.Threading.Dispatcher.RunAsync(
    Windows.UI.Core.CoreDispatcherPriority.Normal,
    () => { }
);

但是System.Windows.Threading命名空间对我来说是不可用的,因为我使用的是.Net 6,它不再受支持。

您知道如何在主线程(UI线程)内部执行非主线程中的代码吗?

3yhwsihp

3yhwsihp1#

我想用C#在.Net 6中的主线程(UI线程)内执行一些非主线程的代码。
我强烈建议您 * 不要 *。让您的async方法使用类似IProgress<T>的东西来根据需要间接更新UI要干净得多。如果您将代码结构化为主线程调用后台线程而不是后台线程通过UI线程来操作UI,那么您将得到一个更加简洁的设计,其中逻辑与UI控件的联系更少。
也就是说,如果您真的想这样做,那么解决方案是在后台工作开始 * 之前 * 捕获 * UI线程上的调度程序,并在将工作发布到UI线程时让后台工作使用 * 该 * 调度程序(而不是“当前调度程序”)。

brccelvz

brccelvz2#

SynchronizationContext是切换到主线程的一个很好的解决方案,但并不是所有的.Net应用程序类型都实现了它。
例如,对于控制台应用程序,没有实施任何解决方案。
但是对于Windows窗体,[WindowsFormsSynchronizationContext][2]可以正常工作。

private SynchronizationContext _synchronizationContext;

内部初始化,调用内部主线程:

_synchronizationContext = new WindowsFormsSynchronizationContext();

之后,您可以从不同的执行绪呼叫:

SynchronizationContext.SetSynchronizationContext(_synchronizationContext);

... here we are in a separate thread

_synchronizationContext.Post(
    (state) => {
        ... this will be executed in the main thread
    },
    null);

相关问题