![]() |
|
Модераторы: Partizan, gambit |
![]()
|
|
| mr.DUDA |
|
|||
|
3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 110 Всего: 232 |
Смотри: есть метод, внутри которого предполагается наличие исключительных ситуаций. Имя этому методу write/read. Для того, чтобы обработать эти ситуации, метод который вызывает write/read, заключает вызовы этих методов в try...catch - и всё пучком... Пока мы не начинаем говорить о многопоточности. В этом случае, тот метод который реализует поток (MainThread), собственно и должен обработать исключение (делай "раз!") и сгенерировать событие (делай "два!"), если он предполагает подписчика на это событие. В данном случае, событие - это прикладная логика, предусматривающая внешний код, который реагирует на наличие исключительных ситуаций. Так или иначе, в любом случае обрабатывать исключения должен тот код, который: - а) сам генерирует исключения - б) вызывает код, генерирующий исключения В том и другом случае, речь всегда идёт об одном потоке. Ответственность за обработку исключений всегда берёт на себя тот, кто вызывает потенциально опасный код. То есть - это либо участок метода, заключенный в try..catch, либо мелкий кусок кода, заключенный в try..catch и вызывающий другой метод. -------------------- ![]() |
|||
|
||||
| -Mikle- |
|
|||
![]() Невидимка Vingrad'а ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1672 Регистрация: 22.6.2003 Где: Казахстан, Астана Репутация: 17 Всего: 59 |
Если само событие ты вызываешь из метода write() или read(), то метод обработки события будет вызываться в том же потоке, что и write/read. Метод m_thread.Join() без параметров, бесконечно ждет завершения потока, а в данном случае он никогда не дождется, так как вызывается из того же потока завершение которого он ждет (надеюсь понятно Добавлено @ 22:11 поясни подробней немного, наверняка нужен просто другой подход -------------------- Если тебе плюют в спину, значит ты впереди... |
|||
|
||||
| zss |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 708 Регистрация: 17.6.2004 Репутация: нет Всего: 2 |
блин... чтож дак все сложно.
Ладно - я все понял. Обработка должна быть при вызове методов, которые могут бросить исключение. Я тогда зайду с другой стороны. Как можно убить объект (или сказать его владельцу). Что его уже буссмысленно использовать и нужно создавать заново. Например если сокет закрылся, то класс, использующий его, использовать бесполезно. При этом нужно что-то сделать извне и заставить заново его создать. |
|||
|
||||
| -Mikle- |
|
|||
![]() Невидимка Vingrad'а ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1672 Регистрация: 22.6.2003 Где: Казахстан, Астана Репутация: 17 Всего: 59 |
Типичная ситуация. Я всегда делал так: 1.Есть класc коллекция объектов mySockColl 2.Есть сам клас mySock использующий сокет, каждый mySock использует свой отдельный Socket 3.Созданием и удалением объектов mySock занимается объект mySockColl (при создании добавляет в коллекцию) 4.У класса mySock есть событие OnDisconnect 5.На этом событие висит метод OnDisconnectHandler(...) в mySockColl 6.Этот метод убивает mySock (получаем от аргумента object sender) и удаляет из коллекции экземпляр mySock (sender) Далее все просто, в самом mySock можно сделать метод, например, void pingSocket(), который проверяет закрылся ли сокет. Если да, то вызвать событие OnDisconnect. Вызывать метод pingSocket() можно перед отправкой или получением данных из сокета. (Вроде-бы я ничего не упустил Добавлено @ 22:42 И вообще, помоему, тема уже переросла в другой раздел -------------------- Если тебе плюют в спину, значит ты впереди... |
|||
|
||||
| ivashkanet |
|
||||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
Срочно читать про события и мультикаст делегаты Вызывая MyEvent(this, e) ты всего лишь по очереди вызываешь методы, зарегистрированные в мультикаст делегате, с одними и теме же параметрами. А так как выполнение инструкций самого метода выполняет поток его вызвавший, то эти методы будут выполняться в том же потоке. В Multicast delegat (делегат на метод возвращающий void) можно регистрировать много методов (объединять их в одну связку). После чего, при вызове делегата, будут вызваны все методы, которые были зарегестрированы (объеденены) в делегате. Евент от делегата отличается только тем, что имеет более удобный способ регистрации методов:
Может где-то я здесь наврал, но суть верна Пример:
|
||||
|
|||||
| zss |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 708 Регистрация: 17.6.2004 Репутация: нет Всего: 2 |
-Mikle-, интересная идея. Тоесть я создаю mySock и подписываюсь у него на событие OnDisconnect.
1. Это схоже с тем, что я впринципе хотел 2. Зачем тогда коллекция ? Достаточно создать класс и самому отслеживать время его жизни. (как правило редко нужно несколько сокетов) 3. Что будет если это событие вызвано из другого потока (про что я и говорил выше - или коллекция это может решить ?) 4. Как пингонуть сокет ? 5 Может у Socket уже есть событие на закрытие ? 6 Какой код ошибки позволит узнать, что исключение было вызванно именно из-за закрытия сокета ? Добавлено @ 09:28
и что это такое ? Это сообщение отредактировал(а) zss - 23.1.2007, 09:56 |
|||
|
||||
| zss |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 708 Регистрация: 17.6.2004 Репутация: нет Всего: 2 |
а если через делегат вызвать AbortThread ? |
|||
|
||||
| -Mikle- |
|
||||||||
![]() Невидимка Vingrad'а ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1672 Регистрация: 22.6.2003 Где: Казахстан, Астана Репутация: 17 Всего: 59 |
Ладно, все по порядку начиная со 2-ого пункта. 2. Не обязательно она должна быть. Это я привел из моего опыта создания сервера АСУДД, когда он должен был держать непрерывную связь с более чем 300 перекрестков (клиентов). И нужна была возможность отправки одного сообщения сразу всем клиентам. Тогда без коллекции (которая в принципе была SocketManager), не обойтись. При этом все соединения были актуальными и SocketManager сам занимался дисконект/конектами, приемкой/отправкой/обработкой сообщений так, что никакой другой объект его использующий не знал ничего. 3. Коллекция (тогда я писал на 1.1 фраймуорке) была простым синхронизированным ArrayList:
Это давало мне возможность не задумываться о том, что и с какого потока вызывалось и как менялась коллекция. Правда foreach итерация должна быть тоже синхронизированной:
До тех пор пока выполняется вышенаписанный цикл (независимо в каком потоке), все остальные потоки не смогут ничего сделать с этой коллекций, а значит это будет безопасно для foreach 4. Например так: bool isDisconnect = Socket.Poll(1, SelectMode.SelectRead); 5. Нету, и наверное не появится. 6. Точно не помню, но помоему вызывается System.ObjectDisposedException
На всякий случай посмотри какой тип объекта Exception вызывается и замени на соответствующий. Если я не ошибся, то помни, что это исключение может вызвать не только Socket, но и любой другой Disposed объект, если ты к нему обратишься в этом try/catch блоке. Но на своей практика я никогда не отлавливал закрытие таким образом, просто все проверял заранее, и никаких исключений не вываливалось
имя метода, который обрабатывает то самое событие, о котором я писал в топике. -------------------- Если тебе плюют в спину, значит ты впереди... |
||||||||
|
|||||||||
| zss |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 708 Регистрация: 17.6.2004 Репутация: нет Всего: 2 |
-Mikle-, спасибо за подробный ответ. Посмотрел MSDN - вроде должет вывалить ObjectDisposedException.
Вопрос чисто теоретический. В С++ есть такая хрень для сокетов Беркли как keep_alive. 1. Кто должет опрашивать - клиент или сервер ? 2. Если сервер, то вопрос снимается, т.к. под С# у меня только клиент, а на сервере это реализовано. А если клиент, то как в C# реализовать опрос сервера если нет обмена. З.Ы. Вопрос возник из-за того, что на GPRS соединении КПК и сервера, если нет обмена данных, то приходит сообщение о том, что сокет разорвал соединение. Не могу понят кто его рвет - клиент или сервер. У меня опрашивает сервер. Может быть С# клиент просто не отвечает и ему нужно об этом как-то сказать ? |
|||
|
||||
| mr.DUDA |
|
|||
|
3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 110 Всего: 232 |
zss,
Модератор: Пожалуйста, один топик - один вопрос. -------------------- ![]() |
|||
|
||||
![]()
|
| Прежде чем создать тему, посмотрите сюда: | |
|
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |