WindowsAppSDK icon indicating copy to clipboard operation
WindowsAppSDK copied to clipboard

`NetworkInformation.GetInternetConnectionProfile()` throws on background threads

Open mattleibow opened this issue 3 years ago • 8 comments

Describe the bug

Previously in UWP, calling the NetworkInformation.GetInternetConnectionProfile() method would return the network information - regardless of the thread used.

In WinUI, this gives a COMException if it is not on a "main" thread.

Original issue: https://github.com/dotnet/maui/pull/10062 Workaround: https://github.com/dotnet/maui/issues/9972

Steps to reproduce the bug

  1. Call NetworkInformation.GetInternetConnectionProfile(); on a background thread/task.

Expected behavior

No exception

Screenshots

No response

NuGet package version

1.1.4

Packaging type

Packaged (MSIX)

Windows version

Windows 10 version 21H2 (19044, November 2021 Update)

IDE

Visual Studio 2022

Additional context

No response

mattleibow avatar Sep 13 '22 14:09 mattleibow

@mattleibow this doesn't repro with the minimal steps provided. For example, this works:

  • Create new WinAppSdk/WinUI app
  • add following code to button click handler, which runs without exception:
private async void myButton_Click(object sender, RoutedEventArgs e)
{
    myButton.Content = "Clicked";

    var profile = await Task.Run(() =>
    {
        return NetworkInformation.GetInternetConnectionProfile().GetNetworkConnectivityLevel();
    });

    myButton.Content = profile;
}

The following code raises an exception when calling GetNetworkConnectivityLevel:

private async void myButton_Click(object sender, RoutedEventArgs e)
{
    myButton.Content = "Clicked";

    var profile = await Task.Run(() =>
    {
        return NetworkInformation.GetInternetConnectionProfile();
    });

    myButton.Content = profile.GetNetworkConnectivityLevel();
}

Also, in the following p1 is correctly set but p2 is null

private async void myButton_Click(object sender, RoutedEventArgs e)
{
    myButton.Content = "Clicked";

    var p1 = NetworkInformation.GetInternetConnectionProfile();
    var profile = await Task.Run(() =>
    {
        var p2 = NetworkInformation.GetInternetConnectionProfile();
        return p2;
    });

    myButton.Content = profile.GetNetworkConnectivityLevel();
}

nickrandolph avatar Sep 22 '22 08:09 nickrandolph

I don't repro this issue. Is there anything specific about how you've created the thread? I tried this:

        private void myButton_Click(object sender, RoutedEventArgs e)
        {
            myButton.Content = "Clicked";
            var thread = new Thread(new ThreadStart(WorkThreadFunction));
            thread.Start();
        }

        public void WorkThreadFunction()
        {
            var profile = NetworkInformation.GetInternetConnectionProfile();
            System.Diagnostics.Debug.WriteLine("Network: profile name: " + profile.ProfileName + " adapter: " + profile.NetworkAdapter);
        }

There is no exception and the debug output looks good. I tried this on Win11 and Win10 21H1.

Note that NetworkInformation is a Windows API and not part of WinAppSDK, so any issue we find here would like require an OS update.

codendone avatar Sep 23 '22 23:09 codendone

I believe the thread was created using the Task.Run() code.

mattleibow avatar Sep 26 '22 15:09 mattleibow

I also think the issue is that the profile was obtained on one thread and then used from another.

    var profile = await Task.Run(() =>
    {
        return NetworkInformation.GetInternetConnectionProfile();
    });

    myButton.Content = profile.GetNetworkConnectivityLevel();

mattleibow avatar Sep 26 '22 15:09 mattleibow

@nickrandolph can you still reproduce this in WinUI?

I tried your code that was failing and it now works. I am reverting our fix as it broke other areas, but it all seems to work now... I have my version numbers of things in the PR: https://github.com/dotnet/maui/pull/10697

If this is still an issue, might be worth attaching your obj\project.assets.json and OS version so we can see exactly what system you have.

mattleibow avatar Oct 14 '22 21:10 mattleibow

I am having the same issue: Target framework: net7.0-windows10.0.19041.0

  "Microsoft.Maui.Dependencies/6.0.312": {
    "type": "package",
    "dependencies": {
      "Microsoft.Graphics.Win2D": "1.0.3.1",
      "Microsoft.Maui.Graphics": "6.0.300",
      "Microsoft.Maui.Graphics.Win2D.WinUI.Desktop": "6.0.300",
      "Microsoft.WindowsAppSDK": "1.0.3"
    }

project.assets.json

Laptop running: Windows 10 Enterprise 19045.3570

I am not using Task.Run or anything, I am using an await on an async service class which has the internet check inside.

I see the MAUI work around issue is "Closed" however the merged fix was reverted.

EDIT I can't keep calling my fetch data API classes on the Main thread as it blocks the UI thread - this seems like a major issue. image

HelenMamalaki avatar Oct 25 '23 16:10 HelenMamalaki

I also think the issue is that the profile was obtained on one thread and then used from another.

    var profile = await Task.Run(() =>
    {
        return NetworkInformation.GetInternetConnectionProfile();
    });

    myButton.Content = profile.GetNetworkConnectivityLevel();

FYI @codendone this snippet is the one that gives me an exception

Foda avatar Nov 29 '23 22:11 Foda

Update: I've observed that this issue only happens on Win10. It works fine on Win11. I've got a VM setup with the behavior if the folks working on this need it.

Foda avatar Dec 04 '23 22:12 Foda