Метод Silverlight Socket.ConnectAsync никогда не вызывает событие Completed

Silverlight Socket.ConnectAsync метод никогда не вызывает событие Completed - я использую 127.0.0.1:4510. Я настроил IIS для обслуживания файла clientaccesspolicy.xml на порту 943.

Я использую следующий код:

        SocketAsyncEventArgs args = new SocketAsyncEventArgs();

        //args.UserToken = tcp;
        args.RemoteEndPoint = ep;
        args.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);

        mrEvent.Reset();
        bool x = tcp.ConnectAsync(args);
        mrEvent.WaitOne();

    private void OnConnect(object sender, SocketAsyncEventArgs e)
    {
        isConnected = (e.SocketError == SocketError.Success);
        mrEvent.Set();
    }

Метод OnConnect никогда не вызывается и, как результат, блокирует код из-за метода WaitOne.

Примечание. Этот код выполняется в фоновом потоке, поэтому из-за вызова WaitOne нет взаимоблокировки.

Ответ 1

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

Я думал, что мой обработчик событий тоже не стрелял. Оказывается, это БЫЛО, но он стрелял по фоновому потоку и не мог повлиять на пользовательский интерфейс. Решение состояло в том, чтобы убедиться, что обработчик запущен в потоке пользовательского интерфейса. Используйте CheckAccess и, если он не в основном потоке, отправьте его туда, используя Dispatcher.BeginInvoke.

Надеюсь, это поможет!

Ответ 2

API-интерфейс Silverlight async socket (единственный доступный) очень плохой. В вашем случае, если значение, возвращаемое с ConnectAsync, равно false, вызов был выполнен синхронно, а метод OnConnect не был вызван.

Вот синхронная версия ConnectAsync:

    public static bool Connect(this Socket socket, EndPoint remoteAddress) {
        ManualResetEvent semaphore = new ManualResetEvent(false);
        SocketAsyncEventArgs socketEventArgs = new SocketAsyncEventArgs() {
            RemoteEndPoint = remoteAddress
        };
        socketEventArg.SetBuffer(buffer, 0, buffer.Length);
        socketEventArg.Completed += (s, e) => {
            semaphore.Set();
        };
        semaphore.Reset();
        bool wasAsynchronous = socket.ConnectAsync(socketEventArgs);
        if (wasAsynchronous) {
            semaphore.WaitOne();
        }
        return socketEventArgs.SocketError == SocketError.Success;
    }