1

我正在尝试从我的 C# 应用程序测试 Windows8 中的 Internet 连接。我有一个布尔类型的变量,它返回连接状态。当布尔值为真时:什么都不做。当布尔值变为假时,加载我的“ 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));
                }
            }
        }
    }
4

2 回答 2

1

使用以下代码,它应该可以解决您的问题...

  Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                if (this.Frame != null)
                {
                    Frame.Navigate(typeof(NetworkDisconection));
                }
            });

您应该能够直接获取 Dispatcher,因为您的代码看起来像是在 XAML 页面的代码隐藏中(参考 this.Frame)。

在 C # Win8 开发论坛中可以找到大量有用的信息。搜索 Dispatcher,你会发现关于它的几个讨论。与往常一样,请查看GenApp以获取其他重要资源。

于 2013-01-16T17:53:45.253 回答
0

该事件在非 UI 线程NetworkInformation.NetworkStatusChanged上引发。与WinFormsWPF类似,您仍然只能访问 UI 线程上的控件。

为了解决这个问题,您必须调用 UI 线程,类似于在WinFormsWPF上使用this.Invoke/的方式this.Dispatcher.Invoke

起初你可能会尝试使用Window.Current.Dispatcher.RunAsync(),但你会注意到它Window.Current总是null在这里。

相反,您应该CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync()Windows.ApplicationModel.Core命名空间中使用。是的,这肯定是相当拗口,所以我推荐App.cs中的这个辅助方法。

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);
}

最后:

async void NetworkInformation_NetworkStatusChanged(object sender)
{
  var isConnected = CheckInternetAccess();

  await ExecuteOnUIThread(() =>
  {        
    if (!isConnected && this.Frame != null)
      this.Frame.Navigate(typeof(ConnectionLostPage));
  });
}
于 2013-01-16T17:59:35.717 回答