0

I am working on an app to iterate through a list of zip codes and business types that will then create a call to the Google Places API (Text Search) via a url that I construct for those parameters.

The url will look something like this

https://maps.googleapis.com/maps/api/place/textsearch/json?key=MY_API_KEY_HERE&sensor=false&query=57783+dentist

The function below is called for each of these requests:

    private static StreamReader MakeWebRequest(string sURL)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sURL);
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        Stream responseStream = response.GetResponseStream();
        StreamReader objReader = new StreamReader(responseStream);
        return objReader;
    }

The problem I am experiencing is that, after 3 to 5 iterations, the response object times out (System.Net.WebException = "The operation has timed out"). My first thought was that the requests were being sent to quickly, so I inserted a Sleep(2000) in the loop, but this seems to have no effect. I have checked the urls that are failing and pasted them into a browser and they do return the proper data.

As I understand it, the only limitation to calls on this api are the 1000 per day I get with an unverified account. What am I missing?

EDIT: Here is the rest of the program block:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Web;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using GooglePlacesJSONGenerator.Models;

namespace GooglePlacesJSONGenerator
{
class Program
{
    static void Main(string[] args)
    {
        //set up a list of zips
        List<string> zipcodeList = new List<string>();
        zipcodeList.Add("57754");
        zipcodeList.Add("57783");
        zipcodeList.Add("57785");

        //setup a list of business types
        List<string> businessTypeList = new List<string>();
        businessTypeList.Add("restaurants");
        businessTypeList.Add("dentist");
        businessTypeList.Add("gym");

        //main data set
        GooglePlaceDataSet places = new GooglePlaceDataSet();

        //base url
        string urlBase = "https://maps.googleapis.com/maps/api/place/textsearch/json?key=MY_API_KEY_HERE&sensor=false&query=";
        string nextUrlBase = urlBase + "&pagetoken=";
        Stream objStream;
        //loop on zip codes
        foreach (string zip in zipcodeList)
        {
            Console.WriteLine("looping on zip " + zip);

            //loop on business type
            foreach (string type in businessTypeList)
            {
                Console.WriteLine("loop on type " + type);

                string sURL;
                string query = HttpUtility.UrlEncode(zip + " " + type);
                sURL = urlBase + query;
                Console.WriteLine("Query String: " + query);
                while (sURL != "")
                {

                    Console.WriteLine("Our URL:  " + sURL);
                    Console.WriteLine("");

                    StreamReader objReader = MakeWebRequest(sURL);

                    JsonTextReader reader = new JsonTextReader(objReader);

                    JsonSerializer se = new JsonSerializer();
                    string parsedData = se.Deserialize(reader).ToString();
                    GooglePlaceDataSet gSet = JsonConvert.DeserializeObject<GooglePlaceDataSet>(parsedData);

                    foreach (GooglePlaceData place in gSet.results)
                    {
                        places.results.Add(place);
                    }

                    if (gSet.next_page_token != null)
                        sURL = nextUrlBase + gSet.next_page_token;
                    else
                    sURL = "";

                    System.Threading.Thread.Sleep(2000);
                }
            }
        }
        Console.ReadLine();
    }
seanicus
  • 1,141
  • 4
  • 19
  • 40
  • Can you post the code where you're calling `MakeWebRequest`? – dtsg Jul 17 '12 at 15:44
  • it would be my pleasure. – seanicus Jul 17 '12 at 15:50
  • Try taking out the `while(sURL != "")` and replace with `if(!string.IsNullOrEmpty(sURL))`. Why are you using a while loop? – dtsg Jul 17 '12 at 15:54
  • It was part of the logic for paging through a result set... the api call only returns 20 at a time... it includes a next_page_token to indicate the presence of additional results that can be fetched. – seanicus Jul 17 '12 at 15:58
  • tried adding the suggested code to no avail. – seanicus Jul 17 '12 at 16:00
  • I was concerned that you were getting stuck in the while loop and `sURL` not being updated with new query string. Does it always fail on the same URL's? I know you've tried them in your browser but what happens if you remove them from your list? – dtsg Jul 17 '12 at 16:05
  • failure is random and not linked to a specific url. – seanicus Jul 17 '12 at 16:06
  • Could be an issue with your `MakeWebRequest` method then, try the following: `HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sURL);` `StreamReader objReader = new StreamReader(request.GetResponse().GetResponseStream());` `return objReader;` – dtsg Jul 17 '12 at 16:11
  • no joy... this is weird. – seanicus Jul 17 '12 at 16:18
  • Indeed! You could try setting your request timeout e.g. `request.Timeout = 2000` etc.... – dtsg Jul 17 '12 at 16:23
  • Have you managed to solve this dude? Curious as to what the issue is here – dtsg Jul 19 '12 at 07:44
  • Yeah, needed to close the StreamReader. Thanks for all the time and help you gave, though! – seanicus Jul 23 '12 at 14:03

2 Answers2

2

The answer was "don't forget the obvious." The StreamReader object needed to be closed. Once I closed it, the above code worked.

seanicus
  • 1,141
  • 4
  • 19
  • 40
0

This could be the result of running up against a threshold value for the maximum number of simultaneous connections from the same source address allowed by the service provider. You must properly Dispose() of your resources either via a using or try/finally, otherwise connections will be held open until the resources are disposed by the garbage collector. See Web response in C# .NET doesn't work more than a couple of times and C# https login and download file, which have related content.

Community
  • 1
  • 1
JamieSee
  • 12,696
  • 2
  • 31
  • 47