我试图从我的C#应用程序测试Windows8中的Internet连接。我有一个类型为Boolean的变量,它返回连接状态。当布尔值为true时:什么都不做。当布尔值变为false时,加载我的" NetworkDisconection
"页。但是,当我调试这一行时:
if (this.Frame != null)
我得到一个例外:
该应用程序调用了一个为不同线程编组的接口。 (来自HRESULT的异常:0x8001010E(RPC_E_WRONG_THREAD))
是的,这个方法是在另一个线程上。我该如何解决这个问题?
private bool bConection;
public HUB()
{
this.InitializeComponent();
bConection = NetworkInformation.GetInternetConnectionProfile()!= null;
NetworkInformation.NetworkStatusChanged += NetworkInformation_NetworkStatusChanged;
}
void NetworkInformation_NetworkStatusChanged(object sender)
{
if (NetworkInformation.GetInternetConnectionProfile() == null)
{
if (bConection == false)
{
bConection = true;
}
}
else
{
if (bConection == true)
{
bConection = false;
if (this.Frame != null)
{
Frame.Navigate(typeof(NetworkDisconection));
}
}
}
}
答案 0 :(得分:1)
使用以下代码,它应该可以解决您的问题......
Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
if (this.Frame != null)
{
Frame.Navigate(typeof(NetworkDisconection));
}
});
您应该能够直接获取Dispatcher,因为您的代码看起来像是在XAML页面的代码隐藏中(对this.Frame的引用)。
可以在C # Win8 Dev Forums中找到大量有用的信息。搜索Dispatcher,您会发现有关它的几个讨论。与往常一样,查看GenApp了解其他优秀资源。
答案 1 :(得分:0)
在非UI线程上引发NetworkInformation.NetworkStatusChanged
事件。与 WinForms 和 WPF 类似,您仍然只能访问UI线程上的控件。
要解决这个问题,您必须使用this.Invoke
/ {{类似于调用 WinForms 或 WPF 的方式调用UI线程1}}。
首先,您可以尝试使用this.Dispatcher.Invoke
,但您会注意到Window.Current.Dispatcher.RunAsync()
始终是Window.Current
。
相反,您应该在null
命名空间中使用CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync()
。是的,确实非常满口,所以我建议在 App.cs 中使用这个辅助方法。
Windows.ApplicationModel.Core
我也会推荐这个辅助方法:
using Windows.ApplicationModel.Core;
using Windows.UI.Core;
public static IAsyncAction ExecuteOnUIThread(DispatchedHandler action)
{
var priority = CoreDispatcherPriority.High;
var dispatcher = CoreApplication.MainView.CoreWindow.Dispatcher;
return dispatcher.RunAsync(priority, action);
}
最后:
public static bool CheckInternetAccess()
{
var profile = NetworkInformation.GetInternetConnectionProfile();
if (profile == null) return false;
var connectivityLevel = profile.GetNetworkConnectivityLevel();
return connectivityLevel.HasFlag(NetworkConnectivityLevel.InternetAccess);
}