2011-10-26 88 views
0

我正在做一个应用程序,做一个IP摄像头的HTTP请求。每次我做一个HTTP请求时,我都会收到一张在屏幕上绘制的图片。所有这些过程都是这样完成的:为什么在不是超时时收到“操作超时”?

  1. 我有一个计时器,每500毫秒调用一次。
  2. 在定时器呼叫做一个http请求线程的代码。

所以有一个很大的可能性,当计时器被调用时,http请求并没有完全完成,这是好的那样。

的问题是,有时,由于未知原因,我收到异常“操作超时”。所以我做了一个操作日志。我记录了http请求之前的时间和之后的时间。它总是在300-400毫秒之间。我也做了一个例外日志,我的惊喜是记录的时间是24或76毫秒。我的超时设置为5000毫秒,所以它永远不会超时!

在我所有的测试中,我从来没有发现一个记录时间超过800毫秒更大,这就是一套超时工作正在进行。

是否有可能解释错误“操作超时”的任何其他原因?我也尝试ServicePointManager.DefaultConnectionLimit = 200;,但它不会改变任何东西。

非常感谢!

这里是螺纹的代码。 ListTest是记录器,每行然后被打印到一个文件。

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); 
} 

*编辑*

要回答的意见,我得到的错误是在System.Net.WebException和err.Message是“操作超时”。

* EDIT 2 *

这里是一个日志我的代码做的一部分。正如你所看到的,超时时间非常短。

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 
+0

你确定它是一个HTTP超时?也许它与你的代码的responseStream部分有关。 – Matthew

+0

你看到的实际例外是什么? –

+0

请参阅上面的修改。 –

回答

3

Timeout值你设置是时间GetResponse响应量。 HttpWebRequest还具有ReadWriteTimeout值,该值在读取或写入时使用。您没有设置ReadWriteTimeout,所以有可能GetResponse在超时时间内返回,但读取超时。

我建议您尝试以下修改:

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; 

补充意见:

你的日志是不完整的,例如,有文件input1_0007一个错误,但没有BEGIN行吧。你的ListTest是一个线程安全的集合吗?如果不是,两个线程同时更新它可能会损坏列表。

而且,你说你的代码发出请求每隔500毫秒。但是你的日志会在一秒钟内显示三个请求。

当然,这并不能解释超时,除非由于某些原因ServicePointManager或其他因为太多未完成的请求而决定杀死它。您可以查看异常堆栈跟踪以查看超时异常的引发位置。

此外,您可能会考虑更改您的代码,以便在完成第一个代码之前,不会再向摄像机发出其他请求。因此,不是每500毫秒触发一次的定时器,而是以500毫秒的延迟启动一次性定时器。定时器回调获取图片,然后重新初始化另一个500毫秒的定时器。这样,对于图片永远不会有一个以上的突出请求,并且避免了奇怪的并发问题。就目前而言,照片可能无序显示。

我认为你有并发问题。如果多个线程可以同时执行此代码(您指出它可能),那么您的ListTest可能会损坏,除非它是某种线程安全的列表。

+0

真的好主意,但不幸它不起作用。我添加了一个日志的一部分,所以你可以看到。 –

+0

@DarkJaff:查看我更新的答案。 –

+0

嗨!为了您的观察,这是日志的修剪版本,缺少一些信息。但是我发现了这个问题,并且您在编辑中是正确的:ServicePointManager在一个线程中使用,但不在另一个线程中使用。当更多的2(默认值)连接同时进行请求时,它发送超时。非常感谢您指出这一点。 –