Socket приостановить асинхронную работу
От: Alexandr Sulimov Украина www.ase.com.ua
Дата: 25.03.10 12:14
Оценка:
Socket работает в асинхронном режиме

IAsyncResult asyncResult = null;
public void StartAsyncReceive()
{
    asyncResult = socket.BeginReceive(
            buffer,
            0, 1,
            SocketFlags.None,
            new AsyncCallback(receiveSrvCallback),
            sdata);
}

public int StopAsyncReceive()
{
    return socket.EndReceive(asyncResult);
}

private void receiveSrvCallback(IAsyncResult ar)
{
    int bytes = StopAsyncReceive();
    //Работа
    StartAsyncReceive();
}


Все работает, но в каокйто момент времени мне нужно читать из сокета вручную
socket.Receive(sdata.buffer, 0, 1, SocketFlags.None);

т.е. чтобы сокет не принимал данные автоматом (receiveSrvCallback)

Но вызов
StopAsyncReceive()
зависает на EndReceive.
Зависание не связано с тем что данных 0?
... << RSDN@Home 1.2.0 alpha 4 rev. 1090>>
Re: Socket приостановить асинхронную работу
От: Jolly Roger  
Дата: 25.03.10 15:51
Оценка:
Здравствуйте, Alexandr Sulimov, Вы писали:

AS>Зависание не связано с тем что данных 0?


Именно с этим и связано. В связи с чем непонятно, чего Вы хотите добиться, ведь Ваш синхронный вызов всё равно зависнет до прихода данных. Если Вам в каком-то месте нужно дождаться прихода данных, то socket.EndReceive именно это и сделает. Кроме того, у IAsyncResult есть свойство WaitHandle, с помощью которого можно ожидать заданное время.
"Нормальные герои всегда идут в обход!"
Re[2]: Socket приостановить асинхронную работу
От: Alexandr Sulimov Украина www.ase.com.ua
Дата: 25.03.10 19:06
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

AS>>Зависание не связано с тем что данных 0?


JR>Именно с этим и связано. В связи с чем непонятно, чего Вы хотите добиться, ведь Ваш синхронный вызов всё равно зависнет до прихода данных. Если Вам в каком-то месте нужно дождаться прихода данных, то socket.EndReceive именно это и сделает. Кроме того, у IAsyncResult есть свойство WaitHandle, с помощью которого можно ожидать заданное время.


В обычном режиме клиент реагирует на данные от сервера (клиент ждет событий).
Но в один момен клиент должен отправить на сервер запрос, и ждать (постояное чтение из сокета) пока прийдет ответ.
И ждать сразу после отправки, а не ждать события ответа от сервер. На это время нужно отключить асинхронное чтение.
... << RSDN@Home 1.2.0 alpha 4 rev. 1090>>
Re[3]: Socket приостановить асинхронную работу
От: Jolly Roger  
Дата: 26.03.10 02:44
Оценка:
Здравствуйте, Alexandr Sulimov, Вы писали:

AS>И ждать сразу после отправки, а не ждать события ответа от сервер. На это время нужно отключить асинхронное чтение.


Не нужно. Для отправки отменять операцию чтения не требуется, а для ожидания ответа есть EndReceive и WaitHandle. С точки зрения упорядочивания ответов сервера тоже нет никакой разницы, будете Вы читать синхронно или асинхронно. Даже если-бы Вы отменили начатое асинхронное чтение, никак нельзя гарантировать, что синхронный receive вернёт Вам именно ответ на последний запрос, а не регулярную посылку(событие).
"Нормальные герои всегда идут в обход!"
Re[4]: Socket приостановить асинхронную работу
От: Alexandr Sulimov Украина www.ase.com.ua
Дата: 26.03.10 08:13
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, Alexandr Sulimov, Вы писали:


AS>>И ждать сразу после отправки, а не ждать события ответа от сервер. На это время нужно отключить асинхронное чтение.


JR>Не нужно. Для отправки отменять операцию чтения не требуется, а для ожидания ответа есть EndReceive и WaitHandle. С точки зрения упорядочивания ответов сервера тоже нет никакой разницы, будете Вы читать синхронно или асинхронно. Даже если-бы Вы отменили начатое асинхронное чтение, никак нельзя гарантировать, что синхронный receive вернёт Вам именно ответ на последний запрос, а не регулярную посылку(событие).


socket в асинхронном режиме, все что приходит попадает в метод receiveSrvCallback из которого дергают клиента чтобы отреагировал.
Теперь клиент:
1. Нажимает кнопку
2. Нужно остановить вызовы receiveSrvCallback чтобы все копилось в буфере
3. Сделать socket.Send(
4. В цикле читать все что прийдет в socket, пока не прийдут нужные данные (могут быть и не нужные, они все равно обрабатываются тут) (в цикл счетчик и он прервется по таймауту)
5. Есть нужный ответ одна реакция на п1.
6. Нет нужноло ответа другая реакция на п1.
7. Продолжить работу socket в асинхронном режиме через receiveSrvCallback
... << RSDN@Home 1.2.0 alpha 4 rev. 1090>>
Re[5]: Socket приостановить асинхронную работу
От: Jolly Roger  
Дата: 26.03.10 09:33
Оценка:
Здравствуйте, Alexandr Sulimov, Вы писали:

AS>socket в асинхронном режиме, все что приходит попадает в метод receiveSrvCallback из которого дергают клиента чтобы отреагировал.

AS>Теперь клиент:
AS>1. Нажимает кнопку
AS>2. Нужно остановить вызовы receiveSrvCallback чтобы все копилось в буфере
AS>3. Сделать socket.Send(
AS>4. В цикле читать все что прийдет в socket, пока не прийдут нужные данные (могут быть и не нужные, они все равно обрабатываются тут) (в цикл счетчик и он прервется по таймауту)
AS>5. Есть нужный ответ одна реакция на п1.
AS>6. Нет нужноло ответа другая реакция на п1.
AS>7. Продолжить работу socket в асинхронном режиме через receiveSrvCallback

Послушайте, я ведь Вас не заставляю Лично я не вижу в этом нумерованном списке ни единой причины отменять асинхрон и переходить на синхронный вызов, но это ведь Ваша задача... Делайте, как считаете нужным
"Нормальные герои всегда идут в обход!"
Re[6]: Socket приостановить асинхронную работу
От: Alexandr Sulimov Украина www.ase.com.ua
Дата: 26.03.10 09:39
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, Alexandr Sulimov, Вы писали:


AS>>socket в асинхронном режиме, все что приходит попадает в метод receiveSrvCallback из которого дергают клиента чтобы отреагировал.

AS>>Теперь клиент:
AS>>1. Нажимает кнопку
AS>>2. Нужно остановить вызовы receiveSrvCallback чтобы все копилось в буфере
AS>>3. Сделать socket.Send(
AS>>4. В цикле читать все что прийдет в socket, пока не прийдут нужные данные (могут быть и не нужные, они все равно обрабатываются тут) (в цикл счетчик и он прервется по таймауту)
AS>>5. Есть нужный ответ одна реакция на п1.
AS>>6. Нет нужноло ответа другая реакция на п1.
AS>>7. Продолжить работу socket в асинхронном режиме через receiveSrvCallback

JR>Послушайте, я ведь Вас не заставляю Лично я не вижу в этом нумерованном списке ни единой причины отменять асинхрон и переходить на синхронный вызов, но это ведь Ваша задача... Делайте, как считаете нужным


Проблема в том что если не отменить
то цикл из п4 начинает "выхватывать" данные (данные читаются по 1 байту)
и receiveSrvCallback читает данные в итоге полных данных нет ни у цикла ни у receiveSrvCallback
зачем 2 читающих, вот одного мне и нужно остановить
... << RSDN@Home 1.2.0 alpha 4 rev. 1090>>
Re[7]: Socket приостановить асинхронную работу
От: Jolly Roger  
Дата: 26.03.10 10:02
Оценка:
Здравствуйте, Alexandr Sulimov, Вы писали:

AS>Проблема в том что если не отменить

AS>то цикл из п4 начинает "выхватывать" данные (данные читаются по 1 байту)
AS>и receiveSrvCallback читает данные в итоге полных данных нет ни у цикла ни у receiveSrvCallback
AS>зачем 2 читающих, вот одного мне и нужно остановить

"данные читаются по 1 байту" — уже плохо для производительности.

Вы можете использовать флаг "ушла команда на сервер" и в обработчике завершения чтения действовать сообразно его состояния. А поток, отправивший команду, при желании можно заблокировать даже своим EventWaitHandle, который обработчик завершения взведёт при получении ответа на команду. И это просто "на вскидку".

Мне не известен способ отменить любой запрос к сокету. Возможно, он существует, но мне он ни разу не понадобился. В принципе, в WinApi есть функция CancelIO, но я понятия не имею, сработает-ли она для сокетов, проверяйте сами.
"Нормальные герои всегда идут в обход!"
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.