Какой смысл передавать состояние методу BeginReceive, если мы работаем только с одним сокетом? Это чтобы избежать использования поля класса? Кажется, что делать это бессмысленно, но, может быть, я что-то упускаю.
Вы правы, если бы вы не использовали штат, вам пришлось бы вместо этого использовать участника. Но это менее локально, чем переменная состояния. Чем больше локальных элементов, тем меньше вероятность их поломки при внесении изменений в другие части кода.
Сравните это с обычными вызовами методов. Почему бы нам просто не установить параметры в качестве членов, а затем вызвать все функции без каких-либо параметров? Это сработало бы ... но было бы ужасно читать код. Сохраняя область действия как можно более локальной, это облегчает понимание и изменение дизайна. Улучшенная инкапсуляция приводит к более надежному коду.
То же самое применимо и здесь. Если у вас есть только один асинхронный обратный вызов, то вы, вероятно, можете просто обойтись без установки члена в классе, но если у вас будет много таких вызовов, эта стратегия вскоре приведет к аналогичным проблемам, как описано выше - запутанный и хрупкий код.
Как может помочь параметр состояния при работе с несколькими сокетами?
Вы можете передавать различные объекты состояния для каждого вызова, каждый из которых содержит свой собственный объект клиента. Обратите внимание, что клиент выбирается из состояния, а не из переменной-члена:
//Socket client = this.client; // Don't do this.
Socket client = state.workSocket;
Если вы заметили, что все другие методы в документации MSDN принимают Client в качестве параметра. Состояние - это просто способ передачи параметров, поскольку сигнатура метода фиксирована.
Обновление. Относительно вашего вопроса в комментариях .NET проверяет, что вы используете правильный клиентский объект и, если нет, выдает ArgumentException
. Из декомпиляции EndReceive в .NET Reflector мы видим это:
if ((result == null) || (result.AsyncObject != this))
{
throw new ArgumentException(SR.GetString("net_io_invalidasyncresult"), "asyncResult");
}