繁体   English   中英

异步和分派器说明

[英]Async and Dispatcher explanation

我有一个使用下面的代码的类。 另外,我正在使用另一个类来检查网络连接的可用性。 此类提供了一个事件,我正在使用该事件来启动和停止计时器。

如果事件被触发,我总是会收到一条错误消息

该应用程序调用了一个已编组为不同线程的接口

public class ViewModel : BindableBase
{

    private DispatcherTimer timerUpdate = null;

    public ViewModel()
    {
        NetworkAvailabilty.Instance.NetworkAvailabilityChanged += OnNetworkAvailabilityChanged;

        timerUpdate = new DispatcherTimer();
        timerUpdate.Interval = TimeSpan.FromMinutes(15);
        timerUpdate.Tick += timerUpdate_Tick;

        if (NetworkAvailabilty.Instance.IsNetworkAvailable)
        {
            timerUpdate.Start();
        }
    }

    private void timerUpdate_Tick(object sender, object e)
    {
        // do something 
    }

    public void OnNetworkAvailabilityChanged(object source, EventArgs e)
    {
        if (NetworkAvailabilty.Instance.IsNetworkAvailable)
        {
             timerUpdate.Start();                
        }
        else
        {
            timerUpdate.Stop();
        }    
    }
} 

因此,经过一些研究,我使用以下代码解决了该问题:

    public void OnNetworkAvailabilityChanged(object source, EventArgs e)
    {
        if (NetworkAvailabilty.Instance.IsNetworkAvailable)
        {
            Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
            () =>
            {
                timerUpdate.Start();
            });

        }
        else
        {
            Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
            () =>
            {
                timerUpdate.Stop();
            });                
        }            
    }

但是,这个问题的背后是什么?代码的这一部分如何防止出现此错误消息? 即使在这里,Visual Studio也会告诉我,我应该考虑在Windows.ApplicationModel .....之前使用await。

但是这个问题的背后是什么

DispatcherTimer在UI线程上创建,这就是所谓的“线程仿射”对象(就像大多数UI组件一样)。 这意味着它“绑定”到其UI线程,现在属于它。

NetworkAvailabilty不是UI组件,它总是在线程池线程上引发NetworkAvailabilityChanged事件。

因此, OnNetworkAvailabilityChanged在线程池线程上运行,并且尝试访问绑定到UI线程的DispatcherTimer 这就是导致异常的原因:

该应用程序调用了一个已编组为不同线程的接口

据说DispatcherTimer被编组用于UI线程(并因此绑定到UI线程),但是您的应用正在从线程池线程中调用其方法之一。

这部分代码如何防止出现此错误消息?

RunAsync在UI线程上执行其委托。

就个人而言,我更喜欢使用SynchronizationContext而不是Dispatcher / CoreDispatcher 如果确实使用了调度程序,则应await调用,并使OnNetworkAvailabilityChangedasync void事件处理程序。

暂无
暂无

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

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