1

I'm using 2 WebClients in my app, for 2 different weather API's.

When my internet connection is slow I get an exception from one of the API's.. It returns a 404 Notfound error.

I have tested this by disabling my WiFi, and put the data connection to '2G'. The first API returns the data with no problem, the second API however crashes my app with a WebException.

When I turn on the WiFi again it works flawlessly. Looks like the second API has a very little patience with slow connections.

Is there a way to fix this? I have also tried to change the WebClient into a HttpWebRequest but the problem still occurs.

Kind regards, Niels

EDIT My code:

    private void GettingTheData()
    {
         WebClient Client = new WebClient();
         Client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(Client _DownloadStringCompleted);

         Client.DownloadStringAsync(new Uri("http://theURI.com"));
    }

void Client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
   {

    string result = e.Result.ToString();
    // Let's do the cool stuff overhere
}
Niels
  • 2,496
  • 5
  • 24
  • 38
  • Can you post the code you are using for your client/webrequest – Shawn Kendrot Jul 03 '13 at 05:21
  • Not a solution, but are you sure you've actually got a working connection from the phone? I've found it can take ages for a 2G connection to be established. I always cross-check by browsing for a known web-site in mobile IE. You should really handle that `WebException`, by the way for cases such as this. – Paul Annetts Jul 03 '13 at 07:45
  • Yes, I do have a working connection because the other Weather API does work.. Slow, but it works. Just looks like that the server of the API that doesn't work when the connection is slow just breaks the connection.. which is resulting is a WebException. I have added my code in the first post. – Niels Jul 03 '13 at 08:09
  • dude you are not going to get a 404 from a slow connection. 404 means the request made it to the web server and the web server said the file is not found. Can you capture the full response and request. More that likely you are hitting some other machine and not the machine with the web service. – user1985513 Jul 10 '13 at 21:37
  • @user1985513, you're wrong. Try to switch off network and send a request. You'll receive exactly the 404 error. – Olter Jul 11 '13 at 05:34
  • 1
    @Niels, the HttpWebRequest.Timeout property most definitely would solve your problem... but it doesn't exist on windows phone. You could try [this](http://stackoverflow.com/questions/15038875/how-to-set-timeout-for-httpwebrequest-in-windows-phone-8-app), perhaps it will work. – Olter Jul 11 '13 at 05:42
  • @Olter, thanks for your comment. I'll try this out tomorrow. Will keep you updated! Should be easy to implement. – Niels Jul 11 '13 at 06:54
  • Olter no thats not how it works. You would timeout because your request never made it to the server. 404 is a http response code. If the request does not make it to the server how do you get a response? – user1985513 Jul 15 '13 at 21:16

3 Answers3

4

There exist HTTP Client library for WP which contains support for timeout. Article about it.

Some sample code for Windows Phone 8:

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
     var httpClient = new HttpClient {Timeout = TimeSpan.FromSeconds(30)};
     var responseBodyAsText = await httpClient.GetStringAsync("www.contoso.com");
}
Teemu Tapanila
  • 1,275
  • 8
  • 20
  • Could you provide the URL's? Since debugging this without those is kinda impossible – Teemu Tapanila Jul 16 '13 at 15:14
  • http://gps.buienradar.nl/getrr.php?lat=52&lon=4 This is the URI that does not always work while on 2G – Niels Jul 17 '13 at 08:14
  • 1
    Actually, I did some re-testing. When TimeSpan.FromSeconds is set to 1 second I get the existing error message, but when its set to 30 it does seem to work correctly :). I have to do some BETA and real world testing, but I guess switching to this does not have any real downsides. Thanks! – Niels Jul 17 '13 at 08:28
  • Using the HTTP Client library is fully supported and most of the libraries that support Portable Class Libraries are already using it completely – Teemu Tapanila Jul 17 '13 at 08:56
  • I did some real-world testing and unfortunately I still get errors: An exception of type 'System.Net.Http.HttpRequestException' occurred in mscorlib.ni.dll and wasn't handled before a managed/native boundary System.Collections.ListDictionaryInternal Response status code does not indicate success: 404 (). at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() – Niels Jul 18 '13 at 10:09
  • You should write there retrying logic in case that it fails – Teemu Tapanila Jul 19 '13 at 04:34
0

Maybe the problem isn't the network latency. Perhaps your second API has a requirement that callers send a user-agent string, or some other HTTP header that you aren't sending. The fact that it works over WiFi and not 2G could have something to do with the fact that any device connecting from your WiFi network would appear to be the same to the server hosting the API (from an IP Address standpoint) and may allow access based on some cached identity (maybe you browsed the service to test it from your development PC). I would be interested to see what would happen if you connected to a different WiFi network if the response would be similar.

My immediate suggestion would be to catch the WebException and give the user a chance to retry.

I would have added this as a comment but I guess I don't have enough reputation for that.

randcd
  • 2,263
  • 1
  • 19
  • 21
  • Thanks for your suggestion. It works perfectly fine on 3G, on multiple devices, and on many different wifi networks. Also the documentation (which is very limited) does not mention any additional strings/HTTP headers whatsoever. Only the '2G' part is weird. Sometimes it works, sometimes it doesn't. – Niels Jul 16 '13 at 06:46
0

Try increasing the ServicePointManager.DefaultConnectionLimit though the default is 2.

Avram Tudor
  • 1,468
  • 12
  • 18