1

I'm trying to test the Internet connection in Windows8 from my C# application. I have a variable of type Boolean that returns me the connection status. When the boolean is true: do nothing. When the boolean becomes false, load my "NetworkDisconection" page. However, when I debug this line:

if (this.Frame != null)

I get an exception:

The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

Yeah, this method is on a different thread. How can I resolve this?

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));
                }
            }
        }
    }
Despertar
  • 21,627
  • 11
  • 81
  • 79
makitocode
  • 938
  • 1
  • 16
  • 40
  • What type of project is this? WPF, Winforms, ? – Despertar Jan 16 '13 at 17:32
  • No, WindowsStore (Windows 8) – makitocode Jan 16 '13 at 17:42
  • ok, i added that tag so it will be easier for people to help. I'm not familiar with windows store apps, but maybe this will help, http://stackoverflow.com/questions/10579027/run-code-on-ui-thread-in-winrt - From the UI thread you access and store the Dispatcher `Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher;` which you can then use to run actions from background threads – Despertar Jan 16 '13 at 17:47

2 Answers2

1

Use the following code and it should fix your problem...

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

You should be able to acquire the Dispatcher directly since it looks like your code is in the code-behind of a XAML page (reference to this.Frame).

Tons of good info can be found in the C# Win8 Dev Forums. Search for Dispatcher and you will find several discussions on it. As always, check out GenApp for other great resources.

Jeff Brand
  • 5,623
  • 1
  • 23
  • 22
0

The NetworkInformation.NetworkStatusChanged event is raised on a non-UI thread. Similar to WinForms and WPF, you are still limited to accessing controls on the UI thread.

To get around this aspect, you'll have to invoke the UI thread similar to how you would on WinForms or WPF using this.Invoke/this.Dispatcher.Invoke.

At first you may try to use Window.Current.Dispatcher.RunAsync() but you will notice that Window.Current is always null here.

Instead, you should use CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync() in the Windows.ApplicationModel.Core namespace. Yeah, that's quite a mouthful for sure so I recommend this helper method in 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);
}

I would also recommend this helper method too:

public static bool CheckInternetAccess()
{
  var profile = NetworkInformation.GetInternetConnectionProfile();

  if (profile == null) return false;

  var connectivityLevel = profile.GetNetworkConnectivityLevel();
  return connectivityLevel.HasFlag(NetworkConnectivityLevel.InternetAccess);
}

And finally:

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

  await ExecuteOnUIThread(() =>
  {        
    if (!isConnected && this.Frame != null)
      this.Frame.Navigate(typeof(ConnectionLostPage));
  });
}
Erik
  • 12,730
  • 5
  • 36
  • 42