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