TCPlistener.BeginAcceptSocket - асинхронный вопрос - PullRequest
1 голос
/ 15 ноября 2009

Некоторое время назад я заплатил программисту за создание многопоточного сервера. Тем временем я немного выучил C # и теперь думаю, что вижу проблему замедления - этот парень сказал мне, что в главном потоке (форме) ничего не обрабатывается, поэтому его нельзя заморозить ... но это так. Но я думаю, что , хотя BeginAcceptSocket является асинхронной операцией, но его обратный вызов выполняется в основном потоке, и, если есть блокировка, это является причиной, по которой приложение зависает. Я прав? Спасибо

    this.mTcpListener.BeginAcceptSocket(this.AcceptClient, null);
  protected void AcceptClient(IAsyncResult ar)
        {
            //some locking stuff
        }

Ответы [ 5 ]

2 голосов
/ 08 июня 2010

Асинхронные методы ввода-вывода Begin / End используют потоки ThreadPool для выполнения делегата обратного вызова, если только операция не может быть завершена немедленно; в этом случае он выполняется синхронно в вызывающем потоке.

С Асинхронный вызов синхронных методов :

Передать делегат для метода обратного вызова в BeginInvoke. Метод выполняется в потоке ThreadPool после завершения асинхронного вызова. Метод обратного вызова вызывает EndInvoke.

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

2 голосов
/ 15 ноября 2009

Нет, AcceptClient() будет не работать в основном потоке.

Лучше покажи некоторые из "запирающих вещей".

1 голос
/ 29 апреля 2010

Я провел небольшой тест winapp, и в результате получается, что даже если метод AcceptClient объявлен в том же классе, что и этот делегат, вызывается из другого потока, а не из основного потока приложения winform, и, таким образом, блокировка НЕ ​​выполняется.

0 голосов
/ 11 июня 2010

Обратный вызов AcceptClient (IAsyncResult ar) может выполняться синхронно.

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

Чтобы быть уверенным, что вы должны остановить приложение под отладчиком, когда оно зависло, и посмотреть, что делает главный поток (событие).

Как правило, лучше иметь отдельный поток для любого ввода / вывода.

0 голосов
/ 15 ноября 2009

Каждый раз, когда ваш код получает блокировку и затем делает что-то, что у вас есть кандидат на узкое место, тем не менее, поток, который вызывает BeginAcceptSocket, не будет заблокирован и может продолжать работать, пока не произойдет событие обратного вызова. Он не будет выполнять обработчик обратного вызова до тех пор, поэтому, в вашем примере, ни одна из блокировок не произойдет, пока с ней не свяжется клиент. Он все еще может зависать в коде принятия, если то, что он делает в этот момент, требует времени или задерживается из-за проблем со связью, но по вашему примеру кода трудно определить, так ли это.

...