Silverlight HttpWebRequest BinaryReader second读取操作总是需要很长时间(1



我正在创建一个Silverlight应用程序,它利用H.264 MediaStreamSource实现,以便从服务器流式传输实时视频。我有一个我写的Multipart streamer,它逐帧读取样本。

当我连接到本地机器上运行的服务器时,从ReadHeaders()函数中的响应流中读取第二个字节需要12秒。所以基本上它立即连接到主机,成功读取一个字节,随后的ReadByte()阻塞(如果你看一下调用堆栈的位置,它在另一个线程中:System.Windows.dll!MS.Internal.InternalNetworkStream)。ReadOperation(对象状态))。每次我测试这个,它总是花费12秒。一旦这段时间过去,所有后续的读取都是即时的,应用程序运行良好。如果我在一个简单的。net控制台应用程序中使用相同的代码,就不会有12秒的延迟。

你知道是什么引起的吗?

byte[] imgBuf = new byte[ChunkSize * ChunkSize];
HttpWebRequest req = (HttpWebRequest)res.AsyncState;
int contentLength = 0;
try
{
HttpWebResponse resp = (HttpWebResponse)req.EndGetResponse(res);
// notify delegate of main headers
// get the response stream and start reading
BinaryReader reader = new BinaryReader(resp.GetResponseStream());
Dictionary<string, string> headers;
while (m_Running)
{
// read multipart response headers and notify delegate
headers = ReadHeaders(reader);
// check if end of stream
if (headers.ContainsKey(CustomHeaders.EndOfStreamHeader) 
&& headers[CustomHeaders.EndOfStreamHeader] != null
&& String.Compare(headers[CustomHeaders.EndOfStreamHeader], "yes") == 0)
{
// notify delegate if end of stream has been reached
}
// determine length of data to read
string cl = headers["Content-Length"];
if (cl != null)
{
contentLength = Int32.Parse(cl);
}
byte[] data = reader.ReadBytes(contentLength);
if (data.Length > 0)
{
// notify delegate of multipart data
}
// Yield to other threads waiting to be executed
System.Threading.Thread.Sleep(1);
}
reader.Close();
resp.Close();
req.Abort();
}
catch (Exception ex)
{
// notify delegate of any errors that occurred
}
ReadHeaders()函数:
private Dictionary<string, string> ReadHeaders(BinaryReader reader)
{
List<byte> buffer = new List<byte>();
while (m_Running)
{
buffer.Add(reader.ReadByte());
if (buffer.EndsWith(EndOfHeaderBytes))
{
break;
}
// Yield to other threads waiting to be executed
System.Threading.Thread.Sleep(1);
}
return buffer.ToHeadersDictionary();
}

编辑:这是两个线程的调用堆栈。

Worker Thread Worker Thread GenIIIWebClient.CVRESTLib.HttpMultipartStreamer.ReadHeaders正常[在休眠,等待或加入]
mscorlib.dll! system . threading . waithhandle . internalwaitone安全处理waitableSafeHandle,长毫秒超时,bool hasThreadAffinity, bool exitContext) + 0x21字节
mscorlib.dll!WaitOne(long timeout, bool exitContext) + 0x21字节
mscorlib.dll!WaitOne(int毫秒超时,bool退出上下文)+ 0x1f字节
mscorlib.dll!System. threading . waitandle .WaitOne() + 0x10字节
System. windows .dll!MS.Internal.InternalNetworkStream.EndRead(System. dll)IAsyncResult asyncResult) + 0x40 bytes
System.Windows.dll!Read(byte[] buffer, int offset, int count) + 0x38字节
mscorlib.dll!System.IO. stream . readbyte () + 0x28字节
mscorlib.dll!System.IO. binaryreader . readbyte () + 0x1d字节
GenIIIWebClient!GenIIIWebClient. cvrestlib . httpmultipartstreamer . readheaders (System.IO. dll)。BinaryReader reader) Line 201 + 0x19 bytes
GenIIIWebClient!GenIIIWebClient. cvrestlib . httpmultipartstreamer . ongetresponse第126行+ 0xf字节
System.Windows.dll!System.Net.Browser.ClientHttpWebRequest.InvokeGetResponseCallbackAnonymousMethod__18(object state2) + 0x11 bytes
mscorlib.dll!System.Threading.QueueUserWorkItemCallback。WaitCallback_Context(object state) + 0x3e bytes
mscorlib.dll!System.Threading.ContextCallback回调,对象状态System.Threading.ThreadPoolWorkQueue.Dispatch() + 0x1b3 bytes
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() + 0x5 bytes
[Native to Managed Transition]
[Appdomain Transition]
[Native to Managed Transition]
[Native to Managed Transition]

未标记5096 5工作线程工作线程[处于睡眠、等待或加入状态]正常[在休眠,等待或加入]
mscorlib.dll! system . threading . waithhandle . internalwaitone安全处理waitableSafeHandle,长毫秒超时,bool hasThreadAffinity, bool exitContext) + 0x21字节
mscorlib.dll!WaitOne(long timeout, bool exitContext) + 0x21字节
mscorlib.dll!WaitOne(int毫秒超时,bool退出上下文)+ 0x1f字节
mscorlib.dll! system . threading . waitandle .WaitOne() + 0x10字节
System.Windows.dll!MS.Internal.InternalNetworkStream. dllReadOperation(object state) + 0x8a bytes
mscorlib.dll!System.Threading.QueueUserWorkItemCallback。WaitCallback_Context(object state) + 0x3e bytes
mscorlib.dll!System.Threading.ContextCallback回调,对象状态System.Threading.ThreadPoolWorkQueue.Dispatch() + 0x1b3 bytes
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() + 0x5 bytes
[Native to Managed Transition]
[Appdomain Transition]
[Native to Managed Transition]
[Native to Managed Transition]

从这里很难看出真正的原因,但它可能与线程管理有关。我看到的第一个嫌疑人是m_Running。专注于此。也许一些线程的东西会因项目的类型而有所不同。

你是否尝试过使用waitHandle而不是给出一个Sleep(1),

ManualResetEvent waitHandle = new ManualResetEvent(false);
while(true)
{
waitHandle.Wait();
waitHandle.Reset();
while(ThereIsAJobToExecute)
{
// Process the jobs
// You should waitHandle.Set() in a callback or when you read it
}
}

我的第二个报价是给出一个初始列表大小

列表& lt;byte> buffer = new List<字节>();

类型List<>的初始大小并不意味着数组大小的限制。如果未给出预定义的大小,则列表会自行调整大小。所以给出一个期望的数字是一个加分项。

List<byte> buffer = new List<byte>(1024...etc);

相关内容

  • 没有找到相关文章

最新更新