Когда вы говорите, что не используете потоки напрямую , я предполагаю, что вы все равно хотите использовать их косвенно через асинхронные вызовы, в противном случае это не очень полезно.
Все, что вам нужно сделать, это обернуть асинхронные методы Stream
и сохранить результат в буфере. Во-первых, давайте определим часть события спецификации:
public delegate void MessageAvailableEventHandler(object sender,
MessageAvailableEventArgs e);
public class MessageAvailableEventArgs : EventArgs
{
public MessageAvailableEventArgs(int messageSize) : base()
{
this.MessageSize = messageSize;
}
public int MessageSize { get; private set; }
}
Теперь, прочитайте одно 16-битное целое число из потока асинхронно и доложите, когда он будет готов:
public class StreamWatcher
{
private readonly Stream stream;
private byte[] sizeBuffer = new byte[2];
public StreamWatcher(Stream stream)
{
if (stream == null)
throw new ArgumentNullException("stream");
this.stream = stream;
WatchNext();
}
protected void OnMessageAvailable(MessageAvailableEventArgs e)
{
var handler = MessageAvailable;
if (handler != null)
handler(this, e);
}
protected void WatchNext()
{
stream.BeginRead(sizeBuffer, 0, 2, new AsyncCallback(ReadCallback),
null);
}
private void ReadCallback(IAsyncResult ar)
{
int bytesRead = stream.EndRead(ar);
if (bytesRead != 2)
throw new InvalidOperationException("Invalid message header.");
int messageSize = sizeBuffer[1] << 8 + sizeBuffer[0];
OnMessageAvailable(new MessageAvailableEventArgs(messageSize));
WatchNext();
}
public event MessageAvailableEventHandler MessageAvailable;
}
Я думаю, вот и все. Это предполагает, что любой класс, обрабатывающий сообщение, также имеет доступ к Stream
и готов читать его, синхронно или асинхронно, в зависимости от размера сообщения в событии. Если вы хотите, чтобы класс наблюдателя действительно прочитал все сообщение, вам нужно добавить еще код для этого.