Сокет, асинхронный прием данных и исключение при вызове метода - PullRequest
1 голос
/ 05 сентября 2011

Я пытаюсь реализовать протокол для обмена мгновенными сообщениями, поэтому использую класс Socket. Когда Socket получает какой-либо пакет данных с сервера, я пытаюсь запустить событие, которое информирует мой другой класс о том, что есть какие-то данные для работы. Но когда я пытаюсь вызвать метод из метода обработчика событий, я получаю сообщение об ошибке: «.NET Compact Framework не поддерживает асинхронный вызов делегатов»

Вот код, с которым я работаю. Я оставил комментарий в строке, где происходит исключение.

public class ClientSocket3
{
    Socket _socket;

    private const int ConnectionTimeout = 5000;
    private static ManualResetEvent connectedDone = new ManualResetEvent(false);

    public OnReceiveHandler3 OnReceive
    {
        get;
        set;
    }

    public void Connect(IPEndPoint endPointAddress)
    {
        _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        SocketAsyncEventArgs args = new SocketAsyncEventArgs();
        args.Completed += new EventHandler<SocketAsyncEventArgs>(args_Completed);
        args.RemoteEndPoint = endPointAddress;
        args.UserToken = _socket;

        _socket.ConnectAsync(args);

        if (connectedDone.WaitOne(ConnectionTimeout))
        {

        }            
    }

    void args_Completed(object sender, SocketAsyncEventArgs e)
    {
        if (e.LastOperation == SocketAsyncOperation.Connect)
        {
            connectedDone.Set();

            Debug.WriteLine("Connected");
        }
        else if (e.LastOperation == SocketAsyncOperation.Receive)
        {
            if (OnReceive != null)
            {
                OnReceive(this, null);
            }
        }
        else if (e.LastOperation == SocketAsyncOperation.Send)
        {
            Debug.WriteLine("Sent... Waiting for answer");

            _socket.ReceiveAsync(e);
        }
    }

    public void Send(byte[] data)
    {
        SocketAsyncEventArgs sendArgs = new SocketAsyncEventArgs();
        sendArgs.Completed += new EventHandler<SocketAsyncEventArgs>(args_Completed);
        sendArgs.SetBuffer(data, 0, data.Length);

        _socket.SendAsync(sendArgs);
    }

    public void Close()
    {
        _socket.Close();
    }
}

public delegate void OnReceiveHandler3(object sender, byte[] receivedData);
 class XYZ
    {
            private ClientSocket3 client;

            public void Connect(IPEndPoint ipep)
            {

                try
                {
                    client = new ClientSocket3();
                    client.Connect(ipep);
                    client.OnReceive += new OnReceiveHandler3(testReceived);

                }
                catch (SocketException se)
                {
                    // todo
                }
                catch
                {
                    throw;
                }
            }

            private void Send(byte[] data)
            {
                    _client.Send(data);
            }

            private void testReceived(object sender, byte[] e)
            {
                    RecvData(e); **// here exception is thrown: Exception: .NET Compact Framework does not support invoking delegates asynchronously**
            }

            private void RecvData(byte[] data) 
            { 
                //....
            }
    }

Исключение выдается сразу после вызова метода Send () из класса XYZ. Конечно, перед отправкой чего-либо я вызываю метод Connect, поэтому я подключен к серверу.

Я пытался работать с ThreadPool.QueueUserWorkItem () и System.Windows.Deployment.Current.Dispatcher.BeginInvoke (), но безуспешно - возможно, я их неправильно использую.

Есть идеи, как это решить? Заранее спасибо.

Обновлено ;

Исключение - стек:

   at Test.IM.XYZ.testReceived(Object sender, Byte[] e)
   at Test.Net.ClientSocket3.args_Completed(Object sender, SocketAsyncEventArgs e)
   at System.Net.Sockets.SocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs e)
   at System.Net.Sockets.SocketAsyncEventArgs.OnCompletedInternal(SocketAsyncEventArgs e)
   at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationSuccess(SocketError socketError, Int32 bytesTransferred, SocketFlags flags)
   at System.Net.Sockets.Socket.AsyncCallback(IAsyncResult ar)
   at System.Net.LazyAsyncResult.InvokeCallback(Boolean asyncCompletion)
   at System.Net.Sockets.Socket.SocketAsyncRequestManager.WorkerThread.doWork()
   at System.Net.Sockets.Socket.SocketAsyncRequestManager.WorkerThread.doWorkI(Object o)
   at System.Threading.ThreadPool.WorkItem.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

Класс исключения: System.NotSupportedException.

In Data is System.Collections.ListDictionaryInternal, но число равно 0

1 Ответ

0 голосов
/ 05 сентября 2011

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

см. MSDN: http://msdn.microsoft.com/en-us/library/system.net.sockets.udpsinglesourcemulticastclient(v=vs.95).aspx

Удачи!

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