Почему асинхронные методы сокетов обратного вызова обычно статичны? - PullRequest
4 голосов
/ 09 сентября 2010

Почему методы сокетов асинхронного обратного вызова обычно статичны?(предположим, я понимаю статический класс, метод и объекты данных).Была бы фундаментальная ошибка проектирования / логики, если бы кто-то написал класс, используя их как методы экземпляра?Есть ли что-то особенное, чего следует избегать?

Ответы [ 3 ]

3 голосов
/ 09 сентября 2010

Нет особой причины, по которой они должны быть статичными. Все зависит от вашего дизайна.

Если обратному вызову требуется доступ к членам класса, он может быть объявлен как член экземпляра. Однако вам необходимо убедиться, что вы правильно синхронизировали доступ к членам экземпляра, потому что обратный вызов может быть вызван одновременно из разных потоков.

Полагаю, что все примеры, которые вы просматривали, передавали необходимые данные в обратный вызов через IAsyncResult.AsyncState, поэтому не требовали дополнительной информации от класса. Если вы можете сделать это, это может упростить ваш код, поскольку вам больше не нужно беспокоиться о синхронизации потоков и т. Д.

Обновление

Просто, чтобы уточнить, основываясь на комментариях, мне кажется, я должен был быть более явным. Дело не в том, что статический обратный вызов будет поточно-ориентированным, а в том, что в проекте, где требуемые данные передаются в обратный вызов и, конечно, эти данные не используются другими потоками, блокировка не требуется. А поскольку обратному вызову передаются все необходимые данные, ему не требуется доступ к экземпляру класса, и поэтому его можно сделать статическим.

1 голос
/ 09 сентября 2010

По крайней мере в C ++ нестатический метод ожидает получить this в качестве скрытого параметра.Поскольку тот, кто вызывает его как обратный вызов, не знает этого, он не будет передавать этот дополнительный параметр.Если бы вам удавалось вызывать нестатическую функцию-член в качестве обратного вызова, все, что пыталось использовать данные члена (что могло бы произойти через this), (почти наверняка) имело бы серьезные проблемы.

Я быдумаю, C # по крайней мере чем-то похож, хотя я недостаточно изучил детали, чтобы знать наверняка.Независимо от языка, код должен знать, с какими данными работать.Очевидное отличие состоит в том, что C # также поддерживает делегаты, которые чрезвычайно полезны для обратных вызовов.

Правка: как избежать этого, по крайней мере в C ++, это довольно просто.Как правило, вы хотите использовать такие библиотеки, как ACE , Boost ASIO или POCO , которые защищают вас от большинства беспорядочных деталей.Если вы оглянетесь вокруг, вы, вероятно, найдете еще как минимум несколько десятков.О, я должен добавить, что большинство библиотек в стиле фреймворка приложения (например, wxWidgets и Qt ) также включают в себя классы, чтобы оградить вас от большинства беспорядочных деталей.Очевидное отличие состоит в том, что они, как правило, «берут на себя» дизайн приложения в целом (хотя, честно говоря, я должен добавить, что ACE имеет тенденцию к тому же).

Конечно, люди написалибиблиотеки для C #, но я не использовал достаточно, чтобы дать им полезные рекомендации.Многое здесь также зависит от того уровня абстракции, который вы ищете.WCF (например) делает гораздо больше, чем просто защищает вас от грязных деталей.Скорее, он строит, по сути, свою собственную полную идею о том, как работать с сетями, что случается (где-то там) с возможностью использовать сокеты - но по большей части, вы действительно не работаете ссокеты больше, вы работаете с WCF, который использует сокеты.

В конце концов, однако, библиотека просто скрывает, а не меняет то, что на самом деле происходит.Где-то внутри библиотеки Winsock выполняет обратный вызов либо статической функции-члена, либо свободной функции, использующей основное соглашение о вызовах C, которое он ожидает.Затем эта функция использует дополнительные данные (обычно передаваемый ей параметр), чтобы выяснить, что вызывать оттуда.Что меняется, так это то, насколько толстый слой «изоляции» существует между вашим кодом и обратным вызовом из Winsock.

1 голос
/ 09 сентября 2010

Функции обратного вызова обычно являются статическими, потому что вы ничего не знаете о классе, для которого вы делаете обратный вызов.

На самом деле функция экземпляра класса обычно несет указатель "this" как скрытыйпервый параметр.

См .: http://www.drdobbs.com/184403375;jsessionid=P5JGJLQBDYGWBQE1GHOSKH4ATMY32JVN?pgno=2

Редактировать: См. также Почему функции обратного вызова должны быть статическими при объявлении в классе

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