[英]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
调用,并使OnNetworkAvailabilityChanged
为async void
事件处理程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.