IO 用の私のアプリケーションは、指定された頻度でデータを送信するサービスに要求を送信します (通常は 1 秒あたり 2 回または 3 回)。15 分または 20 分後、try/catch ブロックではキャッチできない WebException が発生します。BinaryReader.ReadBytes() を使用してデータを読み取ると、例外がスローされます。スタックは次のとおりです。
System.Net.WebException: The operation has timed out.
at System.Net.WebConnectionStream.Read (System.Byte[] buffer, Int32 offset, Int32 size) [0x00048] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/WebConnectionStream.cs:330
at System.IO.BinaryReader.ReadBytes (Int32 count) [0x00051] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.IO/BinaryReader.cs:318
at JpegProcessorLib.FramesProvider.OnGetResponse (IAsyncResult asyncResult) [0x0013f] in /Users/User/Projects/NvrViewer/NvrViewer/Streaming/FramesProvider.cs:146
at System.Net.WebAsyncResult.CB (System.Object unused) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/WebAsyncResult.cs:148
コードは次のとおりです。
private void OnGetResponse (IAsyncResult asyncResult)
{
if (!this.isStreamActive)
{
return;
}
HttpWebResponse resp = null;
byte[] buff = null;
byte[] imageBuffer = new byte[this.approximatelyImageSize];
Stream stream = null;
// get the response
HttpWebRequest req = (HttpWebRequest)asyncResult.AsyncState;
req.GetRequestStream().Close();
resp = (HttpWebResponse)req.EndGetResponse (asyncResult);
// find our magic boundary value
string contentType = resp.Headers ["Content-Type"];
if (!string.IsNullOrEmpty (contentType) && !contentType.Contains ("="))
{
this.PublishFrameReceivingResult(new FrameProviderException ("Invalid content-type header. The camera is likely not returning a proper MJPEG stream."));
return;
}
string boundary = resp.Headers["Content-Type"].Split('=')[1].Replace("\"", "");
byte[] boundaryBytes = Encoding.UTF8.GetBytes(boundary.StartsWith("--") ? boundary : "--" + boundary);
try
{
stream = resp.GetResponseStream();
}
catch(ProtocolViolationException)
{
this.PublishFrameReceivingResult(new FrameProviderException ("Payload was not received from the server"));
return;
}
BinaryReader br = new BinaryReader(stream);
isStreamActive = true;
try
{
buff = br.ReadBytes(this.frameWidth);
}
catch(WebException)
{
br.Close();
resp.Close();
return;
}
while (isStreamActive)
{
int size;
// find the JPEG header
int imageStart = buff.Find(JpegHeader);
if(imageStart != -1)
{
// copy the start of the JPEG image to the imageBuffer
size = buff.Length - imageStart;
Array.Copy(buff, imageStart, imageBuffer, 0, size);
while(true)
{
/*
> System.Net.WebException: The operation has timed out. at System.Net.WebConnectionStream.Read (System.Byte[] buffer, Int32
> offset, Int32 size) [0x00048] in
> /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/WebConnectionStream.cs:330
> at System.IO.BinaryReader.ReadBytes (Int32 count) [0x00051] in
> /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.IO/BinaryReader.cs:318
> at JpegProcessorLib.FramesProvider.OnGetResponse (IAsyncResult
> asyncResult) [0x0013f] in
> /Users/User/Projects/NvrViewer/NvrViewer/Streaming/FramesProvider.cs:146
> at System.Net.WebAsyncResult.CB (System.Object unused) [0x00000] in
> /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/WebAsyncResult.cs:148
*/
try
{
buff = br.ReadBytes(this.frameWidth);
}
catch
{
br.Close();
resp.Close();
return;
}
// find the boundary text
int imageEnd = buff.Find(boundaryBytes);
if(imageEnd != -1)
{
// copy the remainder of the JPEG to the imageBuffer
Array.Copy(buff, 0, imageBuffer, size, imageEnd);
size += imageEnd;
// create a single JPEG image
byte[] currentFrame = new byte[size];
Array.Copy(imageBuffer, 0, currentFrame, 0, size);
this.SaveImage(currentFrame);
// copy the leftover data to the start
Array.Copy(buff, imageEnd, buff, 0, buff.Length - imageEnd);
// fill the remainder of the buffer with new data and start over
byte[] temp = br.ReadBytes(imageEnd);
Array.Copy(temp, 0, buff, buff.Length - imageEnd, temp.Length);
break;
}
// copy all of the data to the imageBuffer
Array.Copy(buff, 0, imageBuffer, size, buff.Length);
size += buff.Length;
}
}
}
resp.Close();
}
誰でも何かアドバイスできますか?