views:

83

answers:

2

here's my method:

private static void UpdatePref(List<EmailPrefer> prefList)
{
    if(prefList.Count > 0)
    {
        foreach (EmailPref pref in prefList)
        {
            UpdateEmailRequest updateRequest = new UpdateEmailRequest(pref.ID.ToString(), pref.Email, pref.ListID.ToString());
            UpdateEmailResponse updateResponse =(UpdateEmailResponse) updateRequest.SendRequest();

            if (updateResponse.Success)
            {
                Console.WriteLine(String.Format("Update Succsesful.  ListID:{0}  Email:{2}  ID:{1}", pref.ListID, pref.Email, pref.ID));
                continue;
            }
            Console.WriteLine( String.Format("Update Unsuccessful.  ListID:{0}  Email:{2}  ID:{1}\n", pref.ListID, pref.Email, pref.ID));
            Console.WriteLine(String.Format("Error:{0}", updateResponse.ErrorMessage));
        }

        Console.WriteLine("Updates Complete.");
    }
    Console.WriteLine("Procses ended.  No records found to update");
}

the list has around 84 valid records that it's looping through and sending an API request for. But it stops on the 3rd API call and only processes 2 out of the 84 records. When I debug to see what's happening, I only see that it stops here in my SendRequest method without spitting out any error. It's stops at the GetRequestStream and when I step to that and try to keep stepping, it just stops and my application stops running without any error!

HttpWebRequest request = CreateWebRequest(requestURI, data.Length);
request.ContentLength = data.Length;
request.KeepAlive = false;
request.Timeout = 30000;

// Send the Request
requestStream = request.GetRequestStream();

wtf? Eventually if I let it keep running I do get the error "The Operation Has Timed Out". But then why did the first 2 calls go through and this one timed out? I don't get it.

Also, a second question. Is it inefficient to have it create a new object inside my foreach for sending and receiving? But that's how I stubbed out those classes and required that an email, ListID and so forth be a requirement to send that type of API call. I just didn't know if it's fine or not efficient to create a new instance through each iteration in the foreach. Might be common but just felt weird and inefficient to me.

A: 

One possibility for it timing out is that the server you're talking to is throttling you. You might try inserting a delay (a second, maybe?) after each update.

Assuming that UpdateEmailRequest and UpdateEmailResponse are somehow derived from WebRequest and WebResponse respectively, it's not particularly inefficient to create the requests the way you're doing it. That's pretty standard. However, note that WebResponse is IDisposable, meaning that it probably allocates unmanaged resources, and you should dispose of it--either by calling the Dispose method. Something like this:

UpdateEmailResponse updateResponse =(UpdateEmailResponse) updateRequest.SendRequest();
try
{
    if (updateResponse.Success)
    {
        Console.WriteLine(String.Format("Update Succsesful.  ListID:{0}  Email:{2}  ID:{1}", pref.ListID, pref.Email, pref.ID));
        continue;
    }
    Console.WriteLine( String.Format("Update Unsuccessful.  ListID:{0}  Email:{2}  ID:{1}\n", pref.ListID, pref.Email, pref.ID));
    Console.WriteLine(String.Format("Error:{0}", updateResponse.ErrorMessage));
}
finally
{
    updateResponse.Dispose();
}

I guess it's possible that not disposing of the response objects keeps an open connection to the server, and the server is timing out because you have too many open connections.

Jim Mischel
A: 

EDIT: It seems you answered your own question already in the comments.

I don't have personal experience with this, but it seems you need to call close on the HTTP web request after you've fetched the response. There's a limit of 2 on the number of open connections and the connection isn't freed until you Close(). See http://blogs.msdn.com/feroze_daud/archive/2004/01/21/61400.aspx, which gives the following code to demonstrate the symptoms you're seeing.

    for(int i=0; i < 3; i++) {
       HttpWebRequest r = WebRequest.Create(“http://www.microsoft.com“) as HttpWebRequest;
       HttpWebResponse w = r.GetResponse() as HttpWebResponse;
    }
Tony Lee
thanks, I ended up also just wrapping it in a using statement to close it. I'll check out that link.