Bug 14705 - problem with DownloadStringAsync from System.Net.WebClient in Xamarin.Android
Summary: problem with DownloadStringAsync from System.Net.WebClient in Xamarin.Android
Status: RESOLVED INVALID
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 4.8.x
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Jonathan Pryor
URL:
Depends on:
Blocks:
 
Reported: 2013-09-12 20:28 UTC by Jon Goldberger [MSFT]
Modified: 2013-10-04 10:11 UTC (History)
2 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
TestCase (26.80 KB, application/x-rar)
2013-09-12 20:28 UTC, Jon Goldberger [MSFT]
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED INVALID

Description Jon Goldberger [MSFT] 2013-09-12 20:28:17 UTC
Created attachment 4864 [details]
TestCase

I'm currently having an issue with the WebClient using Xamarin.Android. I'm on Visual Studio 2012 and I have the Xamarin.Android Alpha build 4.8.2 with the latest Android SDK Tools 22.0.5, SDK Platform-tools 18.0.1.

When I disconnect the wifi on my device and I run a code that try to download string asynchronously, it crashes the whole application, but since the Exception is Internal, I have no way to catch it.

I basically do :

WebClient client = new WebClient();
client.DownloadStringAsync(uri);

Then it crashes when my wifi is disconnected.

Any help would be appreciated.

Call Stack:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
09-12 16:52:01.892 E/mono (15560):
09-12 16:52:01.892 E/mono (15560): Unhandled Exception:
09-12 16:52:01.892 E/mono (15560): at System.Net.WebClient.DownloadDataCore (System.Uri address, System.Object userToken) [0x00000] in <fil09-12 16:52:01.892 E/mono (15560): System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Net.WebException: Error: NameResolutionFailure
09-12 16:52:01.892 E/mono (15560): at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0
09-12 16:52:01.892 E/mono (15560): at System.Net.HttpWebRequest.GetResponse () [0x00000] in <filename unknown>:0
09-12 16:52:01.892 E/mono (15560): at System.Net.WebClient.GetWebResponse (System.Net.WebRequest request) [0x00000] in <filename unknown>:0
09-12 16:52:01.892 E/mono (15560): at System.Net.WebClient.ReadAll (System.Net.WebRequest request, System.Object userToken) [0x00000] in <filename unknown>:0
09-12 16:52:01.892 E/mono (15560): at System.Net.WebClient.DownloadDataCore (System.Uri address, System.Object userToken) [0x00000] in <filename unknown>:0
09-12 16:52:01.892 E/mono (15560): --- End of inner exception stack trace ---
09-12 16:52:01.892 E/mono (15560): at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary () [0x00000] in <filename unknown>:0
09-12 16:52:01.892 E/mono (15560): at System.Net.DownloadStringCompletedEventArgs.get_Result () [0x00000] in <filename unknown>:0
09-12 16:52:01.892 E/mono (15560): at TheKaraokeChannel.Utils.Andro
09-12 16:52:01.892 E/mono-rt (15560): [ERROR] FATAL UNHANDLED EXCEPTION: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Net.WebException: Error: NameResolutionFailure
09-12 16:52:01.892 E/mono-rt (15560): at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0
09-12 16:52:01.892 E/mono-rt (15560): at System.Net.HttpWebRequest.GetResponse () [0x00000] in <filename unknown>:0
09-12 16:52:01.892 E/mono-rt (15560): at System.Net.WebClient.GetWebResponse (System.Net.WebRequest request) [0x00000] in <filename unknown>:0
09-12 16:52:01.892 E/mono-rt (15560): at System.Net.WebClient.ReadAll (System.Net.WebRequest request, System.Object userToken) [0x00000] in <filename unknown>:0
09-12 16:52:01.892 E/mono-rt (15560): at System.Net.WebClient.DownloadDataCore (System.Uri address, System.Object userToken) [0x00000] in <filename unknown>:0
09-12 16:52:01.892 E/mono-rt (15560): --- End of inner exception stack trace ---
09-12 16:52:01.892 E/mono-rt (15560): at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary () [0x00000] in <filename unknown>:0
09-12 16:52:01.892 E/mono-rt (15560): at System.Net.DownloadStringCompletedEventArgs.get_Result () [0x00000] in <filename unknown>:0
09-12 16:52:01.892 E/mono-rt (15560): at TheKaraokeChanne
The program 'Mono' has exited with code 0 (0x0).

----------------------------------------------------------------------------------------------------------
Comment 2 Jonathan Pryor 2013-09-25 14:50:22 UTC
> since the Exception is Internal, I have no way to catch it.

Disable networking on the device. (This can be done in the Settings app.) Run Attachment #4864 [details], then click the "Hello World, Click Me!" button.

Result: it dies, with the aforementioned NameResolutionFailure:

> E/mono    (24880): System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Net.WebException: Error: NameResolutionFailure
> E/mono    (24880):   at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 
> E/mono    (24880):   at System.Net.HttpWebRequest.GetResponse () [0x00000] in <filename unknown>:0 
> E/mono    (24880):   at System.Net.WebClient.GetWebResponse (System.Net.WebRequest request) [0x00000] in <filename unknown>:0 
> E/mono    (24880):   at System.Net.WebClient.ReadAll (System.Net.WebRequest request, System.Object userToken) [0x00000] in <filename unknown>:0 
> E/mono    (24880):   at System.Net.WebClient.DownloadDataCore (System.Uri address, System.Object userToken) [0x00000] in <filename unknown>:0 
> E/mono    (24880):   --- End of inner exception stack trace ---
> E/mono    (24880):   at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary () [0x00000] in <filename unknown>:0 
> E/mono    (24880):   at System.Net.DownloadStringCompletedEventArgs.get_Result () [0x00000] in <filename unknown>:0 
> E/mono    (24880):   at DownloadStringAsync_TestBed.W

HOWEVER, that exception is NOT internal; it's a result of invoking the DownloadStringCompletedEventArgs.Result property, which throws DownloadStringCompletedEventArgs.Error:

https://github.com/mono/mono/blob/master/mcs/class/System/System.Net/DownloadStringCompletedEventArgs.cs#L45
https://github.com/mono/mono/blob/master/mcs/class/System/System.ComponentModel/AsyncCompletedEventArgs.cs#L46

The fix, then, is that WebRequestAsyncAndroid.ClientDownloadStringCompleted() should not access the DownloadStringCompletedEventArgs.Result property unless it first checks that DownloadStringCompletedEventArgs.Cancelled is false and DownloadStringCompletedEventArgs.Error is null. By doing so, the "internal" exception can be avoided:

  private void ClientDownloadStringCompleted(object sender,
      DownloadStringCompletedEventArgs e)
  {
    if (e.Cancelled || e.Error != null) {
      Console.WriteLine(
          "# ClientDownloadStringCompleted: Cancelled={0}; Error={1}",
          e.Cancelled, e.Error);
      return;
    }
    if (DownloadStringCompleted != null) {
      DownloadStringCompletedEventArgs d =
        new DownloadStringCompletedEventArgs(e.Error, e.Cancelled,
            e.UserState, e.Result));
      DownloadStringCompleted(this, d);
    }
  }
Comment 3 mlpstingray 2013-10-04 09:53:26 UTC
Any reason why this is invalid would have been apreciated.
Comment 4 mlpstingray 2013-10-04 09:55:33 UTC
Nevermind, I misread the result.
Comment 5 mlpstingray 2013-10-04 10:11:52 UTC
Thanks for your help!