2017-12-02 76 views
0

我正在编写一个基于here示例的简单TCP服务器。 而不是回显收到的数据我想保持打开套接字发送和接收更多的数据。执行动作<T>出队后

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

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(); 

编译器说:

错误CS7036没有给出说法,对应于所需形式参数“OBJ” '行动'。

很明显,我没有通过论证,但我不明白我应该在哪里以及如何找回它。

+0

也许你想排队的字符串,只是调用相同的行动或方法? – kenny

+0

摆脱(x) – kenny

+0

x可能有效,但对我来说似乎是一种解决方法。我在lambda表达式中传递了“data”参数。它去了哪里? – Mark

回答

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()