Вызов BeginRead из NetworkStream

Хорошо, я хочу подключиться к Socket и прочитать сетевой поток, используя класс System.Net.Sockets.NetworkStream. Это то, что у меня есть до сих пор:

NetworkStream myNetworkStream;
Socket socket;

socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, 
    ProtocolType.IPv4);
socket.Connect(IPAddress.Parse("8.8.8.8"), 8888);

myNetworkStream = new NetworkStream(socket);

byte[] buffer = new byte[1024];
int offset = 0;
int count = 1024;

myNetworkStream.BeginRead(buffer, offset, count, ??, ??);

Теперь мне нужны AsyncCallback и Object state, чтобы завершить метод BeginRead, но я даже не уверен, что это сработает. Я немного потерялся в этот момент! Куда мне нужно идти отсюда?


person JMK    schedule 10.11.2011    source источник
comment
Вы на ложном пути. Используйте пример кода библиотеки MSDN для Socket.BeginReceive().   -  person Hans Passant    schedule 10.11.2011
comment
У вас есть причина использовать асинхронную версию? Разве вы не можете просто использовать Read()?   -  person svick    schedule 10.11.2011
comment
Будет ли это работать? В конце концов, я хочу, чтобы эта служба работала постоянно, но сейчас я просто хочу увидеть некоторые результаты. И еще, спасибо Ганс, я посмотрю.   -  person JMK    schedule 10.11.2011


Ответы (1)


По сути, когда вы вызываете метод Begin* для асинхронной операции, должен быть вызов соответствующего оператора End* (более подробную информацию см. в Обзор асинхронного программирования в MSDN, особенно раздел "Завершение асинхронной операции").

Тем не менее, вы обычно хотите передать метод/анонимный метод/лямбда-выражение, которое будет делать одну или две вещи:

1) Вызвать соответствующий метод End*, в данном случае Stream.EndRead . Этот вызов не будет блокироваться при вызове, потому что callback не будет вызываться до тех пор, пока операция не будет завершена (обратите внимание, что если во время асинхронного вызова возникнет исключение, это исключение будет вызвано при вызове метода End*).

2) Возможно начать новый асинхронный вызов. В этом случае предполагается, что вы захотите прочитать больше данных, поэтому вам следует начать новый вызов Stream.BeginRead

Предполагая, что вы хотите сделать № 2, вы можете сделать следующее:

// Declare the callback.  Need to do that so that
// the closure captures it.
AsyncCallback callback = null;

// Assign the callback.
callback = ar => { 
    // Call EndRead.
    int bytesRead = myNetworkStream.EndRead(ar);

    // Process the bytes here.


    // Determine if you want to read again.  If not, return.
    if (!notMoreToRead) return;

    // Read again.  This callback will be called again.
    myNetworkStream.BeginRead(buffer, offset, count, callback, null);
};

// Trigger the initial read.
myNetworkStream.BeginRead(buffer, offset, count, callback, null);

Однако, если вы используете .NET 4.0, это становится намного проще с помощью метода FromAsync< /a> в классе TaskFactory.

person casperOne    schedule 10.11.2011
comment
В качестве альтернативы, если вы используете .NET Framework 4.5+ или .NET Standard/Core, вы можете использовать Stream.ReadAsync в методе async - person GGG; 15.03.2018