简体   繁体   English

如何分派到主线程?

[英]How to dispatch to main thread?

I would like to execute some code from a non-main thread inside the main thread (UI thread) in.Net 6 with C#.我想使用 C# 从 .Net 6 中主线程(UI 线程)内的非主线程执行一些代码。

I've tried to use this code:我试过使用这段代码:

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

This doesn't work, since Windows.UI.Core.CoreWindow.GetForCurrentThread() returns null .这不起作用,因为Windows.UI.Core.CoreWindow.GetForCurrentThread()返回null

My second try was:我的第二次尝试是:

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

This fails, because Windows.ApplicationModel.Core.CoreApplication.MainView throws a System.InvalidOperationException .这失败了,因为Windows.ApplicationModel.Core.CoreApplication.MainView抛出System.InvalidOperationException

Another way should be:另一种方式应该是:

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

But the System.Windows.Threading namespace is not available for me, since I'm using.Net 6 and it's not longer supported in it.但是System.Windows.Threading命名空间对我不可用,因为我使用的是 .Net 6,它不再受支持。

Any idea, how I can execute some code from a non-main thread inside the main-thread (UI thread)?任何想法,如何从主线程(UI 线程)内的非主线程执行一些代码?

I would like to execute some code from a non-main thread inside the main thread (UI thread) in.Net 6 with C#.我想使用 C# 在.Net 6 中的主线程(UI 线程)内的非主线程中执行一些代码。

I strongly recommend that you don't .我强烈建议你不要 It's far cleaner to have your async methods use something like IProgress<T> to indirectly update the UI as necessary.让您的async方法使用IProgress<T>之类的方法在必要时间接更新 UI 会干净得多。 If you structure your code so that the main thread calls the background threads instead of the background threads manipulating the UI through the UI thread, then you'll end up with a much cleaner design where your logic is less tied to your UI controls.如果您构建代码以便主线程调用后台线程而不是后台线程通过 UI 线程操作 UI,那么您最终会得到一个更简洁的设计,您的逻辑与 UI 控件的联系更少。

That said, if you really want to, then the solution is to capture the dispatcher on the UI thread before the background work begins, and have the background work use that dispatcher (not the "current dispatcher") when posting work to the UI thread.也就是说,如果您真的想要,那么解决方案是在后台工作开始之前在 UI 线程上捕获调度程序,并让后台工作在将工作发布到 UI 线程时使用调度程序(而不是“当前调度程序”) .

SynchronizationContext is a good solution to switch to the main thread. SynchronizationContext是切换到主线程的一个很好的解决方案。 But it's not implemented for all.Net app types.但它并未针对所有 .Net 应用程序类型实施。

For example, for a console app, there is no solution implemented.例如,对于控制台应用程序,没有实施解决方案。

But for Windows Forms, WindowsFormsSynchronizationContext works fine.但对于 Windows 窗体, WindowsFormsSynchronizationContext工作正常。

private SynchronizationContext _synchronizationContext;

Initialization inside, called inside the main thread:里面初始化,在主线程里面调用:

_synchronizationContext = new WindowsFormsSynchronizationContext();

After this, you can call from a different thread:在此之后,您可以从不同的线程调用:

SynchronizationContext.SetSynchronizationContext(_synchronizationContext);

... here we are in a separate thread

_synchronizationContext.Post(
    (state) => {
        ... this will be executed in the main thread
    },
    null);
            await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync
            (CoreDispatcherPriority.Normal, () =>
            {
            do something on UI thread
             });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM