0

いくつかのコードから始めましょう:

class InternetConnector
{
    private struct ConnectionData
    {
        public Action<Socket> SuccessHandler { get; set; }
        public ClientStateObject clientObj { get; set; }
        public Action<Exception> ErrorHandler { get; set; }
        public Socket Socket { get; set; }
    }
    public static ManualResetEvent processingDone = new ManualResetEvent( false );
    public static ConcurrentQueue<string> messages = new ConcurrentQueue<string>();

    public bool ReceiveMessage(Action<Socket> successHandler, Action<Exception> errorHandler)
    {
        ClientStateObject obj = new ClientStateObject();
        obj.server = client;
        var connectionData = new ConnectionData
        {
            ErrorHandler = errorHandler,
            SuccessHandler = successHandler,
            Socket = client,
            clientObj = obj
        };
        if (Connected)
        {
            client.BeginReceive(connectionData.clientObj.buffer, 0, ClientStateObject.bufSize, 0, new AsyncCallback(ReceiveCallback), connectionData);
            receive = true;
            receiveDone.WaitOne();
        }
        return receive;
    }

    private static void ReceiveCallback(IAsyncResult ar)
    {
        ConnectionData connectionData = new ConnectionData();
        bool complete = false;
        try
        {
            connectionData = (ConnectionData)ar.AsyncState;
            Socket client = connectionData.Socket;
            int num = client.EndReceive(ar);
            {
                connectionData.clientObj.stringBuffer.Append(Encoding.ASCII.GetString(connectionData.clientObj.buffer, 0, num));
                string response = connectionData.clientObj.stringBuffer.ToString();
                string[] msgs = response.Split('&');
                for (int i = 0; i < msgs.Count(); i++)
                {
                    string sts = msgs[i];
                    messages.Enqueue(sts + "&" );
                }
                receiveDone.Set();
                if (connectionData.SuccessHandler != null)
                {
                    connectionData.SuccessHandler(client);
                    processingDone.WaitOne();
                    client.BeginReceive(connectionData.clientObj.buffer, 0, ClientStateObject.bufSize, 0, new AsyncCallback(ReceiveCallback), connectionData);
                }
            }
        }
        catch (Exception e)
        {
            if (connectionData.ErrorHandler != null)
                connectionData.ErrorHandler(e);
        }
    }

public partial class Form1 : Form
{
    private InternetConnector client = new InternetConnector();
    private bool isRunning = false;

    private void AsyncSuccessHandler(Socket socket)
    {
        if (InvokeRequired)
        {
            BeginInvoke(new Action( () => AsyncSuccessHandler( socket ) ));
            return;
        }
        if (InternetConnector.messages.Count() == 0)
        {
            status.Text = "Signals Receiver: Connected";
            status.ForeColor = Color.Green;
            isRunning = true;
            client.ReceiveMessage(AsyncSuccessHandler, AsyncErrorHandler);
        }
        else
        {
            GUIChangeOnConnection();
            InternetConnector.processingDone.Set();
        }
    }

    private void GUIChangeOnConnection()
    {
            for( int i = 0; i < InternetConnector.messages.Count; i++ )
            {
                string message;
                InternetConnector.messages.TryDequeue( out message );
// process the message
            }
    }
 }

今問題。

すべて正常に動作します。ソケットからの読み取りが行われています。ただし、への呼び出しが早すぎるprocessingDone.WaitOne();までコールバックを無期限にブロックする必要がある呼び出し。processingDone.Set();

GUIChangeOnConnection();- 関数の閉じ括弧行の最後にブレークポイントを設定して確認しました。ブレークポイントに到達InternetConnector.messagesし、キューが空ではないことがわかります。これは、for ループが終了していないことを意味します。そして、このブレークポイントに 2 回到達すると、キュー内のメッセージ数が急増します。

私は何を間違っていますか?それとも私のデザインが間違っているのでしょうか?

ありがとうございました。

4

0 に答える 0