Windows runtime 是否每个WinRT/Windows核心线程都有一个调度程序?

Windows runtime 是否每个WinRT/Windows核心线程都有一个调度程序?,windows-runtime,windows-10-universal,windows-10-iot-core,winrt-async,Windows Runtime,Windows 10 Universal,Windows 10 Iot Core,Winrt Async,我们提供了一个库,它需要在自己的自定义线程上运行代码。完成后,我希望这些线程通过调度程序(System.Windows.Threading.Dispatcher)调用回调(事件处理程序)。库用户应使用调度器将事件处理分派给 我们可以总是在CoreApplication.MainView.corewindown.Dispatcher上调度,但并非所有程序(例如Windows 10 IoT核心应用程序)都提供UI,因此它们缺少主窗口 用户是否可以简单地引用以获取其线程的调度程序?或者不能所有线程都有

我们提供了一个库,它需要在自己的自定义线程上运行代码。完成后,我希望这些线程通过
调度程序
System.Windows.Threading.Dispatcher
)调用回调(事件处理程序)。库用户应使用调度器将事件处理分派给

我们可以总是在
CoreApplication.MainView.corewindown.Dispatcher上调度,但并非所有程序(例如Windows 10 IoT核心应用程序)都提供UI,因此它们缺少主窗口

用户是否可以简单地引用以获取其线程的
调度程序
?或者不能所有线程都有一个调度程序

编辑:下面是这个问题的更多上下文。希望它能让问题更容易理解:

或者不能所有线程都有一个调度程序

调度程序线程始终绑定到UI线程。物联网无头模式应用程序没有UI,因此没有调度程序线程

用户是否可以简单地参考System.Windows.Threading.Dispatcher.CurrentDispatcher来获取其线程的调度程序

System.Windows.Threading.Dispatcher.CurrentDispatcher仅在旧式.NET平台中受支持。正如您所指出的,UWP替代方案是CoreApplication.MainView.CoreWindow.Dispatcher


如果您想在无头(无GUI)模式下执行异步回调,您可能可以参考任务并行库(TPL)、ContinueWhallContinueWhenny等API。。。可能很适合你的需要。首先,我不确定您是否应该在UI线程上执行事件处理程序,因为只有客户端知道是否需要访问UI元素

其次,在调用
CoreApplication.MainView
属性之前,您可以检查
CoreApplication.Views.Count>0
(我不确定它是否能工作,因为目前我没有设备来测试它)

您还可以用另一种方法解决这个问题:在对象的构造函数中保存执行线程的SynchronizationContext,然后使用它引发事件。如果您的对象从UI线程实例化(在大多数情况下是真的),那么它将起作用。这样你就可以完全拒绝调度员的请求

public class NotifierExample
{
    private readonly SynchronizationContext _synchronizationContext;


    public event EventHandler SomethingHappened;


    public NotifierExample()
    {
        _synchronizationContext = SynchronizationContext.Current;
    }


    public void Do()
    {
        Task.Factory.StartNew(() =>
        {
            //do something
            OnSomethingHappened();
        });
    }


    private void OnSomethingHappened()
    {
        if (_synchronizationContext != null)
        {
            _synchronizationContext.Post(o => RaiseSomethingHappened(), null);
        }
        else
        {
            RaiseSomethingHappened();
        }
    }

    private void RaiseSomethingHappened()
    {
        var somethingHappened = SomethingHappened;
        somethingHappened?.Invoke(this, EventArgs.Empty);
    }
}

为什么要在UI线程上执行事件处理程序?当某些对象在后台(非UI)线程上引发事件时,这是非常常见的情况。如果您库的用户需要访问事件处理程序中的UI元素,则必须使用Dispatcher来处理此事件。WPF的行为非常不直观,使许多程序员陷入麻烦,这里有很多关于它的问题。WinRT没有重复这个错误,您只能从窗口获取一个调度程序。这是一种合乎逻辑的方法,只有当窗口是由具有分派循环的线程创建时,它才能工作,没有该循环,它就像门钉一样死掉。如果您没有窗口,那么您也不再需要在特定线程上运行代码。但需要从UI线程创建/初始化对象。这是你的案子吗?我的意思是,它只在从UI线程创建对象的情况下才有效。或者,例如,您可以在订阅的同一线程上引发事件处理程序,但这不是一个简单的解决方案。我更新了问题以提供更多上下文。亲爱的Jackie,感谢您的回答。不幸的是,该任务不是由库用户启动的,而是由库在任何时间点启动的(实际上是来自蓝牙设备的回调)。尽管如此,任务是否涉及并不重要,因为我的问题是将
事件操作
分派到用户希望分派到的线程上。特别是关于这个问题:@LarsBlumberg,你是否考虑使用SynchronizationContext.Post?根据headless模式,您可以将同步上下文设置为UI或一些非UI线程。看起来很棒!get headless应用程序从何处获得其
SynchronizationContext
?我们不会强制用户在UI线程上运行处理程序。但是库需要从库的事件发生在自定义线程上这一事实中抽象出来——如果作为库用户,您必须将所有回调同步到主线程以更新UI(如果有的话),这就很不方便了。使用
SynchronizationContext
看起来很棒–将尝试一下!