我寫了下面的C#功能:功能讀取線被阻斷
static string ReadLineCRLF(System.IO.Stream Stream, ref byte[] sharedBuffer, int bufferSize = 1024)
{
StringBuilder responseString = new StringBuilder("");
string returnString = "";
byte[] buffer = new byte[bufferSize];
bool stopreading = false;
bool firstexecution = true;
while (!stopreading)
{
int readBytes;
if (firstexecution && sharedBuffer.Length > 0)
{
readBytes = sharedBuffer.Length;
sharedBuffer.CopyTo(buffer, 0);
}
else
{
readBytes = Stream.Read(buffer, 0, bufferSize); //BLOCKING HERE
}
firstexecution = false;
if (readBytes > 0)
{
int crIndex = Array.IndexOf(buffer, (byte)13); //13 = ASCII value for a carriage return
if (crIndex > -1 && Array.IndexOf(buffer, (byte)10, crIndex + 1) == crIndex + 1) //10 = ASCII value for line feed
{
stopreading = true;
sharedBuffer = readBytes - crIndex - 2 > 0 ? ArraySlice<byte>(buffer, crIndex+2, readBytes-crIndex-2) : new byte[] { };
readBytes = crIndex;
}
if (readBytes > 0)
{
responseString.Append(System.Text.Encoding.ASCII.GetString(buffer, 0, readBytes));
}
if (stopreading)
{
returnString = responseString.ToString();
}
}
if (!stopreading && readBytes <= 0)
{
returnString = null;
stopreading = true;
sharedBuffer = new byte[] { };
}
}
return returnString;
}
此功能是根據我的籌碼資源管理器,使用了大量的電腦性能在readBytes = Stream.Read(buffer, 0, bufferSize);
阻塞。這個函數應該做的唯一事情就是從一個只由CRLF(「\ r \ n」)結束的流中讀取一行。
根據MSDNStream.Read
返回less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.
,它通常應該阻止並不會耗盡CPU性能。 The implementation will block until at least one byte of data can be read, in the event that no data is available. Read returns 0 only when there is no more data in the stream and no more is expected (such as a closed socket or end of file)
。
那麼爲什麼它 - 根據我的CLR堆棧資源管理器 - 使用瞭如此多的性能(高達70%)?我沒有看到任何邏輯錯誤,我認爲它應該等到某些字節可以被接收。似乎這種行爲並不總是發生,但在Windows服務器上開始執行應用程序一兩天後。
其他說明: 由於使用塊讀取字節,可能會有太多的字節被讀取並存儲在緩衝區中。因此我使用共享緩衝區,允許它再次使用它來繼續閱讀下一行。一行完全讀取後,我將其從緩衝區中刪除。
的ArraySlice功能如下:
public static T[] ArraySlice<T>(T[] data, int index, int length)
{
T[] result = new T[length];
Array.Copy(data, index, result, 0, length);
return result;
}
爲什麼不簡單地使用StreamReader?它會給你你需要的線。 –
因爲一條線必須完全以CRLF結束。 'StreamReader.ReadLine'也接受簡單的CR和LF。這是因爲一些RFC規範。 –