Вызов BeginRead из NetworkStream - PullRequest
       29

Вызов BeginRead из NetworkStream

4 голосов
/ 10 ноября 2011

Хорошо. Я хочу подключиться к 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 метода, но я даже не уверен, сработает ли это. Я немного растерялся на этом этапе! Куда мне нужно идти отсюда?

1 Ответ

13 голосов
/ 11 ноября 2011

Обычно, когда вы вызываете метод 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 метод в TaskFactory классе .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...