2017-12-02 11 views
0

hereに基づいて単純なTCPサーバーを作成しています。 受信したデータをエコーするのではなく、より多くのデータを送受信できるようにソケットを開いたままにします。 、私は「データ」の値を取得する方法を理解していないデキュー後にアクション<T>を実行

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

:私は私のデータをキュー

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

コンパイラは言う:

エラーCS7036を必要と仮引数 "objのに対応して与えられた引数はありません「行動」の

私は議論に合格しませんでしたが、どこでどのように取得する必要があるのか​​分かりません。

+0

多分あなたは文字列をキューに入れたいだけで、同じアクションをまたはメソッドと呼ぶのでしょうか? – kenny

+0

xを(x)で取り除く – kenny

+0

それはうまくいくかもしれませんが、私にとっては回避策のようです。ラムダ式の "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()

関連する問題