views:

5007

answers:

6

I have big problem. I need send 200 objects at a time,

here is my code :

while (true)
{

    NameValueCollection myNameValueCollection = new NameValueCollection();
    myNameValueCollection.Add("mode", nat);
    myNameValueCollection.Add("mode", nat);


    using (var client = new WebClient())
    {
        byte[] responseArray = client.UploadValues(serverA, myNameValueCollection);

        answer= Encoding.ASCII.GetString(responseArray);
        answer= Convert.ToString(answer);
        string[] split = 
            Javab.Split(new[] { '!' }, StringSplitOptions.RemoveEmptyEntries);
        string comand = split[0];
        string sever= split[1];
        string op1 = split[2];
        string op2 = split[3];
        string op3 = split[4];
        switch (comand)
        {
            case "check":
                int ops1 = Convert.ToInt32(op1);

                for (int i = 0; i < ops1; )
                {
                    Uri myUri = new Uri(server);
                    WebRequest myWebRequest = WebRequest.Create(myUri);
                    myWebRequest.Timeout = 200000;
                    WebResponse myWebResponse = myWebRequest.GetResponse();
                    i++;
                }
                break;
        }
    }    
}

and i get this error

Unhandled Exception: System.Net.WebException: The operation has timed out
   at System.Net.HttpWebRequest.GetResponse()
   at vir_fu.Program.Main(String[] args)

a part of code , like this

for (int i = 0; i < ops1; )
{
    Uri myUri = new Uri(site);
    WebRequest myWebRequest = WebRequest.Create(myUri);
    myWebRequest.Timeout = 200;
    WebResponse myWebResponse = myWebRequest.GetResponse();
    i++;
}

Work great out side of my base code , but when I add this code in my project I get that error , i tried set timeout = 200 ; but didn't work.

What can i do?

A: 

I remember I had the same problem a while back using WCF due the quantity of the data I was passing. I remember I changed timeouts everywhere but the problem persisted. What I finally did was open the connection as stream request, I needed to change the client and the server side, but it work that way. Since it was a stream connection, the server kept reading until the stream ended.

Freddy
+5  A: 

It means what it says. The operation took too long to complete.

BTW, look at WebRequest.Timeout and you'll see that you've set your timeout for 1/5 second.

John Saunders
A: 

I'm not sure about your first code sample where you use WebClient.UploadValues, it's not really enough to go on, could you paste more of your surrounding code? Regarding your WebRequest code, there are two things at play here:

  1. You're only requesting the headers of the response**, you never read the body of the response by opening and reading (to its end) the ResponseStream. Because of this, the WebRequest client helpfully leaves the connection open, expecting you to request the body at any moment. Until you either read the response body to completion (which will automatically close the stream for you), clean up and close the stream (or the WebRequest instance) or wait for the GC to do its thing, your connection will remain open.

  2. You have a default maximum amount of active connections to the same host of 2. This means you use up your first two connections and then never dispose of them so your client isn't given the chance to complete the next request before it reaches its timeout (which is milliseconds, btw, so you've set it to 0.2 seconds - the default should be fine).

If you don't want the body of the response (or you've just uploaded or POSTed something and aren't expecting a response), simply close the stream, or the client, which will close the stream for you.

The easiest way to fix this is to make sure you use using blocks on disposable objects:

for (int i = 0; i < ops1; i++)
{
    Uri myUri = new Uri(site);
    WebRequest myWebRequest = WebRequest.Create(myUri);
    //myWebRequest.Timeout = 200;
    using (WebResponse myWebResponse = myWebRequest.GetResponse())
    {
        // Do what you want with the HEAD response.
    } // Your response will be disposed of here
}

Another solution is to allow 200 concurrent connections to the same host. However, unless you're planning to multi-thread this operation so you'd need multiple, concurrent connections, this won't really help you:

 ServicePointManager.DefaultConnectionLimit = 200;

When you're getting timeouts within code, the best thing to do is try to recreate that timeout outside of your code. If you can't, the problem probably lies with your code. I usually use cURL for that, or just a web browser if it's a simple GET request.

** In reality, you're actually requesting the first chunk of data from the response, which contains the HTTP headers, and also the start of the body. This is why it's possible to read HTTP header info (such as Content-Encoding, Set-Cookie etc) before reading from the output stream. As you read the stream, further data is retrieved from the server. WebRequest's connection to the server is kept open until you reach the end of this stream (effectively closing it as it's not seekable), manually close it yourself or it is disposed of. There's more about this here.

Matthew Brindley
@Matthew: are you sure about sending `HEAD`? I don't think I've ever seen that happen.
John Saunders
Sorry, I don't mean HEAD (HEAD's where you request *only* the headers), I mean the initial response contains only the headers (which is what you'd normally get if you just sent a HEAD request). I've edited to fix my mistake.
Matthew Brindley
@Matthew: again, what makes you think the response only contains headers? Are you suggesting there's another packet exchange between the client and server at the time that the `GetRequestStream` is called?
John Saunders
hi matthew B , thank you for responds ,ok my code do this :1 - start while(true)//work right1 - post data to serverA//work right2 - receive code//work right3 - use switch(code)//work right4 - send GET request to serverB //problem is here 5 - sleep for 2ming6 - end of while();
@John I've just done some testing with MS Network Monitor to see what happens while WebRequest does it stuff. WebRequest does exchange packets with the server when the stream is read, it seems. However, for small files, GetResponse downloads the entire body, but keeps the connection active. For anything bigger, it only requests more of the file as the user begins to read the stream. I've updated my answer with more info.
Matthew Brindley
+1  A: 

Hi

I was using CoockComputing for xmlrpc web service calls, I tried to transfer some 9000 objects through web services, I'm having the same problem.

what I'm doing right now if inside the for loop, I'm having System.Net.WebException Exception, I tried to call the same service again 3 times and if each time I'm getting the same Exception then I Terminate the Application, I never had such Exception when I worked with localhost, but when I called the Remote Web Services I'm getting such Exception.

Currently I don't have any option so I tried trial & error method till counter reaches 3.

and it also depends on the Internet if your internet is slow / un reachable to the requested call it may cause System.Net.WbeException TimedOut !!!.

Tumbleweed
What do you have your timeout set to? He has his set to 200 milliseconds.
John Saunders
the default timeout value in XmlRpc.NET is 100 seconds. I have also tried with 20000,40000 miliseconds, but still as when it goes for the remote call sometimes I got the timedout exception so I used 3-counter logic for that.
Tumbleweed
+1  A: 

Close/dispose your WebResponse object.

Joe Chung
Good catch, but you should show him how, or else I will.
John Saunders
A: 

Hi Zimzim/John/Metthew,

I am also facing timeout problem in my code. Actually in my code i am connecting with Weather.com for weather by using following code

string connectionString = string.Format ("http://xoap.weather.com/weather/local/{0}?cc=*&amp;prod=xoap2&amp;par={1}&amp;key={2}", locID, partnerID, licenseKey);

        connectionString += (units == WeatherUnits.Metric) ? "&unit=m" : "&unit=s";
        this.iconSize = iconSize;
        this.iconLocation = iconLocation;
        this.partnerID = partnerID;
        this.locationID = locID;

        // The Implementation Guide instructs to cache current conditions for 30 minutes
        wd = (WeatherDataSet) HttpContext.Current.Cache ["WeatherDS:" + locID];

        if (wd == null)
        {
            StringReader    rdr = null;
            XmlDocument     doc = new XmlDocument ();
            WebRequest req = WebRequest.Create(connectionString);
            req.Proxy = WebProxy.GetDefaultProxy();
            req.Proxy.Credentials = CredentialCache.DefaultCredentials;  
            WebResponse resp = req.GetResponse();
            StreamReader textReader = new StreamReader(resp.GetResponseStream());
            XmlTextReader xmlReader = new XmlTextReader(textReader);
            doc.Load(xmlReader);                
            rdr = new StringReader (doc.InnerXml);

            /* 
                * The tricky part about interpreting a response from Weather.com is that in either
                * case it's an XML document. We'll peek inside the response to sniff for an error
                * and if there's none load it into our strongly-typed weather info dataset.
                */
            if (doc.SelectSingleNode ("/error/err") == null)
            {
                wd = new WeatherDataSet ();
                wd.ReadXml (rdr);            
                HttpContext.Current.Cache.Insert ("WeatherDS:" + locID, wd, null, DateTime.Now.AddMinutes (30), TimeSpan.Zero, CacheItemPriority.NotRemovable, null);
            }
            else
            {
                // If some error was returned we need to throw an exception
                WeatherDataError err = new WeatherDataError ();
                err.ReadXml (rdr);
                throw new Exception (err.err[0].err_Text);
            }

            rdr.Close ();
        }

Here i am making connection by using WebRequest.Create() method . This method sometimes take more than 40 second to respond connection failure.

John can you help me for default timeout value. Should i explicitly write timeout value? and what that should be?

Hemant Kothiyal