出列

时间:2017-12-02 20:20:05

标签: c#

我正在编写一个基于示例here的简单TCP服务器。 我希望保持套接字打开以发送和接收更多数据,而不是回显收到的数据。

因此,我改变了一些功能如下:

public readonly ConcurrentQueue<Action<String>> actions = new ConcurrentQueue<Action<String>>();

public void AcceptCallback(IAsyncResult ar)
{
    allDone.Set();

    Connected.Invoke(this, new EventArgs());
    Socket listener = (Socket)ar.AsyncState;
    Socket handler = listener.EndAccept(ar);

    StateObject state = new StateObject
    {
        workSocket = handler
    };
    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);

    while (handler.Connected)
    {
        if (actions.TryDequeue(out Action<String> action))
        {
            try
            {
                action(/* ??? */);
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        Thread.Sleep(0); 
    }
}

public void SendData(String data)
{
    Socket handler = state.workSocket;
    byte[] byteData = Encoding.ASCII.GetBytes(data);
    handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
}

在外部线程中我将数据排入队列:

 String data = "something";
 server.actions.Enqueue((x) => server.SendData(data));

我不明白如何在使Action出列后检索“数据”值。 “action”实际上是一个Action,但是当我尝试调用它时:

action();

编译器说:

  

错误CS7036没有给出的参数对应于'Action'所需的形式参数'obj'。

很明显我没有通过论证,但我无法理解我应该在何处以及如何检索它。

1 个答案:

答案 0 :(得分:3)

你的问题在这里:

server.actions.Enqueue((x) => server.SendData(data));

您已经在闭包中捕获data,为什么需要参数x?只需存储将调用server.SendData(data)的操作:

server.actions.Enqueue(() => server.SendData(data));

当然,您需要相应地更改actions的类型:

public readonly ConcurrentQueue<Action> actions =
    new ConcurrentQueue<Action>();

现在您可以按照以下方式调用操作:action()