异步和调度程序说明

时间:2017-01-04 19:49:55

标签: c# events async-await uwp

我有一个使用以下代码的课程。另外我使用另一个类来检查我的网络连接的可用性。这个类提供了一个事件,我用它来启动和停止计时器。

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

  

应用程序调用了为不同线程编组的接口

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

1 个答案:

答案 0 :(得分:4)

  

但问题背后的原因是什么

在UI线程上创建了

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

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

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

  

应用程序调用了为不同线程编组的接口

它说DispatcherTimer为UI线程编组(因此绑定到UI线程),但是你的应用程序正在从线程池线程中调用其中一个方法。

  

这部分代码如何阻止此错误消息?

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

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

相关问题