Проблема с AsyncCallback в C # .NET 3.5 - PullRequest
2 голосов
/ 05 октября 2010

Я создал однопоточное приложение Windows, которое взаимодействует с более чем 100 сокетами (используя AsyncCallbacks), может быть 5-10 сокетов в секунду.

Приложение работает нормально при запуске из .NET IDE.,Приложение кажется зависшим, если оно запускается из исполняемого файла.В ходе дальнейших исследований я обнаружил, что приложение отлично взаимодействует с сокетами, только данные в интерфейсе не обновляются.Кажется, что приложение слишком загружено для чтения из сокетов, чем для обновления пользовательского интерфейса.

Приложение прекрасно работает при замене AsyncCallback отдельным потоком для каждого сокета, но это не очень хороший подход.

Я пытался создать очереди сообщений, но это не помогло.

Правильно ли я сказал, что приложение занято чтением в сокете, чем обновление пользовательского интерфейса?Как я могу решить эту проблему?

Код, который я использую для AsynCallBack, указан ниже.

    private void ConnectSocket()
    {
        IPEndPoint ipEnd = new IPEndPoint(_ip, _port);
        m_socket = new Socket(ipEnd.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        m_socket.Blocking = false;
        m_socket.ReceiveBufferSize = RECEIVE_BUFFER_SIZE;
        m_socket.NoDelay = true;
        m_socket.LingerState = new LingerOption(false, 0);

        AsyncCallback onconnect = new AsyncCallback(OnConnect);
        m_socket.BeginConnect(ipEnd, onconnect, m_socket);
    }

    private void OnConnect(IAsyncResult ar)
    {
        Socket sock = (Socket)ar.AsyncState;
        try
        {
            sock.EndConnect(ar);
            if (sock.Connected)
            {
                SetupReceiveCallback(sock);
            }
        }
        catch (Exception ex)
        {
        }
    }

    private void SetupReceiveCallback(Socket sock)
    {
        try
        {
            AsyncCallback receiveData = new AsyncCallback(ReceiveData);
            sock.BeginReceive(receivedBuffer, 0, receivedBuffer.Length,
                SocketFlags.None, receiveData, sock);
        }
        catch (SocketException ex)
        {
        }
        catch (Exception ex)
        {
        }
    }

    private void ReceiveData(IAsyncResult ar)
    {
        Socket sock = (Socket)ar.AsyncState;
        try
        {
            int numBytesReceived = sock.EndReceive(ar);

            if (numBytesReceived > 0)
            {
                if (OnReceivedData != null)
                {
                    OnReceivedData(receivedBuffer);
                }
            }
            SetupReceiveCallback(sock);
        }
        catch (SocketException ex)
        {
            //If error code is 1054 then socket connection is terminated from the client.
        }
        catch (Exception ex)
        {
        }
    }

1 Ответ

1 голос
/ 08 ноября 2010

Было бы очень странно, чтобы приложение было настолько загруженным, что оно зависает.Что вызывает функция ConnectSocket()?Если это вызывается для события пользовательского интерфейса (например, когда нажата кнопка), то оно будет выполняться в потоке пользовательского интерфейса, и пользовательский интерфейс будет блокироваться до его завершения.Вам нужно будет запустить отдельный поток в фоновом режиме для обработки соединений, если вы хотите, чтобы ваш пользовательский интерфейс продолжал работать.

Вы можете использовать класс ThreadPool для запуска фоновых потоков для обработкисоединения.

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