我有一个使用以下代码的课程。另外我使用另一个类来检查我的网络连接的可用性。这个类提供了一个事件,我用它来启动和停止计时器。
如果事件被触发,我总会收到错误消息
应用程序调用了为不同线程编组的接口
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答案 0 :(得分:4)
在UI线程上创建了但问题背后的原因是什么
DispatcherTimer
,它就是所谓的“线程仿射”对象(就像大多数UI组件一样)。这意味着它“绑定”到其UI线程,现在属于它。
NetworkAvailabilty
不是UI组件,它总是在线程池线程上引发其NetworkAvailabilityChanged
事件。
因此,OnNetworkAvailabilityChanged
正在线程池线程上运行,它尝试访问绑定到UI线程的DispatcherTimer
。这就是导致异常的原因:
应用程序调用了为不同线程编组的接口
它说DispatcherTimer
为UI线程编组(因此绑定到UI线程),但是你的应用程序正在从线程池线程中调用其中一个方法。
这部分代码如何阻止此错误消息?
RunAsync
在UI线程上执行其委托。
就个人而言,我更喜欢使用SynchronizationContext
而不是Dispatcher
/ CoreDispatcher
。如果您确实使用了调度程序,则应await
进行调用并使OnNetworkAvailabilityChanged
成为async void
事件处理程序。