C# 执行操作<;T>;排队后

C# 执行操作<;T>;排队后,c#,C#,我正在基于这个示例编写一个简单的TCP服务器。 我希望保持套接字打开以发送和接收更多数据,而不是回显接收到的数据 因此,我对一些函数进行了如下更改: public readonly ConcurrentQueue<Action<String>> actions = new ConcurrentQueue<Action<String>>(); public void AcceptCallback(IAsyncResult ar) { all

我正在基于这个示例编写一个简单的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);
}
我不明白在退出操作队列后如何检索“数据”值。“action”实际上是一个action,但当我尝试调用它时:

action();
编者说:

错误CS7036未给出与“Action”的必需形式参数“obj”对应的参数

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

您的问题在于:

server.actions.Enqueue((x) => server.SendData(data));
您已经在闭包中捕获了
数据
,为什么需要参数
x
?只需存储将调用服务器的操作。SendData(data):

当然,您需要相应地更改
操作的类型

public readonly ConcurrentQueue<Action> actions =
    new ConcurrentQueue<Action>();
公共只读ConcurrentQueue操作=
新的ConcurrentQueue();
现在,您可以按照自己的意愿调用操作:
action()

您的问题在这里:

server.actions.Enqueue((x) => server.SendData(data));
您已经在闭包中捕获了
数据
,为什么需要参数
x
?只需存储将调用服务器的操作。SendData(data):

当然,您需要相应地更改
操作的类型

public readonly ConcurrentQueue<Action> actions =
    new ConcurrentQueue<Action>();
公共只读ConcurrentQueue操作=
新的ConcurrentQueue();

现在,您可以像您希望的那样调用操作:
action()

也许您希望队列中的字符串能够调用相同的操作或方法?去掉(x)中的x它可能会工作,但对我来说似乎是一种解决方法。我在lambda表达式中传递了“data”参数。它到哪里去了?当您调用它时,然后传递null,因为x未使用DDoS未编译:委托操作不接受参数0可能您希望队列中的字符串并只调用相同的操作或方法?去掉(x)中的x可能会起作用,但对我来说似乎是一种解决方法。我在lambda表达式中传递了“data”参数。它到哪里去了?当调用它时,传递null,因为x未被使用。不编译:委托操作不接受参数0