I'm doing an application that do HTTP request to an IP camera. Each time I do an HTTP request, I receive a picture that draw on the screen. All this process is done like this:
So there is a big possibility that when the timer is called, the http request is not completely done and it's ok like that.
The problem is that sometime, for an unknown reason, I receive the exception "The operation has timed out". So I did a log of the operation. I log the time before the http request and the time after. It's always arround 300-400 ms. I also did a log in the exception and my big surprise was that the logged time is like 24 or 76 ms. My timeout is set to 5000 ms so it should never timeout!
In all my test, I've never found a logged time bigger than 800 ms and that's way under the set timeout.
Is there any other reason that could explain the error "Operation has timed out"? I also try ServicePointManager.DefaultConnectionLimit = 200;
but it doesn't change anything.
Thanks a lot!
Here is the code that is threaded. The ListTest is the logger, each line is then printed to a file.
StructTakePicture structTP = (StructTakePicture)structTakePicture;
ServicePointManager.DefaultConnectionLimit = 200;
string strFileName = structTP.FolderGUID + "input" + GetNumeroPhoto(structTP.Cam.ID, structTP.NumPhoto) + ".jpg";
DateTime dateDebut = DateTime.Now;
try
{
ListTest.Add(strFileName + " --- BEGIN : " + dateDebut.ToString());
WebRequest WebRequestObject = HttpWebRequest.Create(String.Format("http://{0}/mjpg/snapshot.cgi?camera={1}", structTP.Cam.TotalIP, structTP.Cam.View));
WebRequestObject.Timeout = 5000;
WebRequestObject.Credentials = new NetworkCredential("admin", "admin");
HttpWebResponse ResponseObject = (HttpWebResponse)WebRequestObject.GetResponse();
string strTypeRetour = ResponseObject.ContentType;
if (strTypeRetour == "image/jpeg")
{
MemoryStream memoryStream = new MemoryStream(0x10000);
using (Stream responseStream = WebRequestObject.GetResponse().GetResponseStream())
{
byte[] buffer = new byte[0x1000];
int bytes;
while ((bytes = responseStream.Read(buffer, 0, buffer.Length)) > 0)
{
memoryStream.Write(buffer, 0, bytes);
}
ResponseObject.Close();
}
byte[] response = memoryStream.ToArray();
Image img = byteArrayToImage(response);
img.Save(strFileName);
structTP.StopEverything = false;
DateTime dateFin = DateTime.Now;
TimeSpan span = dateFin.Subtract(dateDebut);
ListTest.Add(strFileName + " --- TOTALTIME:" + span.Milliseconds.ToString());
ListTest.Add(strFileName + " --- END : " + dateFin.ToString());
}
}
catch (System.Net.WebException err)
{
structTP.StopEverything = true;
DateTime dateFin = DateTime.Now;
TimeSpan span = dateFin.Subtract(dateDebut);
ListTest.Add(strFileName + " === ERROR :" + span.Milliseconds + " | " + err.Message);
}
* EDIT *
To answer the comments, the error I get is in the System.Net.WebException and the err.Message is "Operation has timed out".
* EDIT 2 *
Here is a part of a log I did with the code. As you can see, the timeout is received with very tiny response time.
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00013.jpg --- BEGIN : 2011-10-27 08:16:46
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00010.jpg --- TOTALTIME:353
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00010.jpg --- END : 2011-10-27 08:16:47
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00006.jpg --- TOTALTIME:610
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00006.jpg --- END : 2011-10-27 08:16:47
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00008.jpg --- BEGIN : 2011-10-27 08:16:47
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00014.jpg --- BEGIN : 2011-10-27 08:16:47
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00009.jpg --- BEGIN : 2011-10-27 08:16:47
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00005.jpg --- TOTALTIME:996
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00005.jpg --- END : 2011-10-27 08:16:48
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00004.jpg --- TOTALTIME:800
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00004.jpg --- END : 2011-10-27 08:16:48
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00007.jpg === ERROR :22 | The operation has timed out
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00015.jpg --- BEGIN : 2011-10-27 08:16:48
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00014.jpg --- TOTALTIME:391
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00014.jpg --- END : 2011-10-27 08:16:49
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00009.jpg === ERROR :23 | The operation has timed out
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00008.jpg --- TOTALTIME:526
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00008.jpg --- END : 2011-10-27 08:16:50
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00012.jpg --- TOTALTIME:461
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00012.jpg --- END : 2011-10-27 08:16:50
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00015.jpg --- TOTALTIME:780
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00015.jpg --- END : 2011-10-27 08:16:50
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00011.jpg --- TOTALTIME:49
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00011.jpg --- END : 2011-10-27 08:16:50
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00009.jpg --- TOTALTIME:133
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00009.jpg --- END : 2011-10-27 08:16:50
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00007.jpg --- TOTALTIME:140
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00007.jpg --- END : 2011-10-27 08:16:51
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00013.jpg === ERROR :28 | The operation has timed out
C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00010.jpg --- BEGIN : 2011-10-27 08:16:56
The Timeout
value you're setting is the amount of time for the GetResponse
to respond. The HttpWebRequest
also has a ReadWriteTimeout value that is used when reading or writing. You're not setting ReadWriteTimeout
, so it's possible that GetResponse
is returning within the timeout, but the read is timing out.
I would suggest you try the following modification:
HttpWebRequest WebRequestObject = (HttpWebRequest)HttpWebRequest.Create(String.Format("http://{0}/mjpg/snapshot.cgi?camera={1}", structTP.Cam.TotalIP, structTP.Cam.View));
WebRequestObject.Timeout = 5000;
WebRequestObject.ReadWriteTimeout = 5000;
Additional observations:
Your log is incomplete, for example, there's an ERROR for file input1_0007
, but no BEGIN line for it. Is your ListTest
a thread-safe collection? If not, two threads updating it at the same time could very well corrupt the list.
Also, you said that your code is making a request every 500 ms. But your log shows three requests within a single one-second period.
Granted, that doesn't explain the timeout, unless for some reason the ServicePointManager
or something else decided to kill it because of too many outstanding requests. You might look at the exception stack trace to see where the timeout exception was thrown.
Also, you might consider changing your code so that it never makes another request to the camera until the first one is done. So instead of a timer that fires every 500 ms, you start a one-shot timer with a 500 ms delay. The timer callback gets the picture and then re-initializes the timer for another 500 ms. This way, there is never more than one outstanding request for a picture, and you avoid weird concurrency problems. As it stands now, it's possible for pictures to be displayed out of order.
I think you're having concurrency problems. If multiple threads can be executing this code at the same time (you indicated that it is possible), then your ListTest
can get corrupted unless it's a thread-safe list of some kind.