【问题标题】:Async and Dispatcher explanationAsync 和 Dispatcher 解释
【发布时间】:2017-01-05 04:53:41
【问题描述】:

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

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

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

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.....

【问题讨论】:

    标签: c# events async-await uwp


    【解决方案1】:

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

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

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

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

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2021-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多