2017-11-06 2 views
0

ラムダとデリゲートの新人ですが、簡単にするためにいくつかの既存のメソッドを書きたいと思います。C#ラムダデリゲート内のメソッドを残す

背景:ソケットを介して通信するクライアントアプリケーションとサーバーアプリケーションがあります。 CommunicationMessageは、送受信する値を保持するクラスです。

アクションをパラメータとして持つメソッドを定義しました。

public void SendAndReceive(CommunicationMessage query, Action<CommunicationMessage> OnReceivedResponse, Action<int> OnReceivedError, Action OnFailedSending) { ... } 

このメソッドは次のように呼び出されます:あなたは私はそのラムダデリゲート内からメソッドを残したい見ることができるように

public static void LoginUser(string email, string password) 
    { 
     // Create the query which will be sent to the Server 
     CommunicationMessage query = MessageContentGenerator.GenerateLoginQuery(email, password).Result; 

     // Perorm the sending operation 
     CommunicationController.SendAndReceive(query, 
      (response) => 
      { 
       BaseUser user = BaseUserController.Parse(response); 
       ... 
      }, 
      (errorCode) => 
      { 
       // From here I want to leave the method LoginUser() 
      }, 
      () => 
      { 
      } 
     ); 
    } 

。これを達成する方法はありますか?

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

答えて

0

応答を取得するためにTask<CommunicationMessage>を返す別のメソッドを定義することができます(これはコアメソッドと同じです)。次に、そのコアメソッドに基づいて返されるTask<BaseUser>を定義します。すべてはこのように、TaskCompletionSourceを使用して行うことができます。

public Task<CommunicationMessage> SendAsync(CommunicationMessage query, Action<int> OnReceivedError, Action OnFailedSending) { 
    var tcs = new TaskCompletionSource<CommunicationMessage>(); 
    SendAndReceiveAsync(query, cm => tcs.TrySetResult(cm), OnReceivedError, OnFailedSending); 
    return tcs.Task; 
} 
//for BaseUser result 
public static async Task<BaseUser> LoginUserAsync(string email, string password) 
{ 
    // Create the query which will be sent to the Server 
    var query = MessageContentGenerator.GenerateLoginQuery(email, password).Result; 
    var result = await SendAsync(query, (errorCode) => {},() => {}); 
    return BaseUserController.Parse(result); 
} 

あなたがのawaitで使用することができますawaitableメソッドに(コールバック付き)伝統の非同期メソッドをオンにするその利益を取るためにTaskCompletionSourceについての詳細を見つけることができます。 try-catchをシームレスに使用できるように、エラーを処理し例外を発生させることもできます(エラーコールバックを使用する必要はありません)。

+0

はい私はこれを普通に好きですが、このタイプの実装から離れ、デザインパターンにもっと集中したいと思います。私は物事をクリアするために少しトピックを編集しました。 –

+0

@DanielDirtyNativeMartinまだ私はあなたの問題が(あなたがここでコメントしたものと混同して)理解していません。実際にあなたが今持っているものと同じように設計された 'SendAndReceiveAsync'メソッドでは、私がここで提供した解決策は非常によく知られており、(async/awaitを利用する利点を得るための)良い習慣として従うべきです。 'SendAndReceiveAsync'のデザインを変更することができれば、ただちに非同期をサポートするためにすぐに進んで、' Task'の代わりに 'Task 'を待ちます。次に、パターン間の変換に特別なメソッドは必要ありません –

+0

このメソッドにasyncを使用する必要はありませんが、これは単なる例です。だから私は再びそれを編集した。私は2番目のラムダ内から* LoginUser *メソッド全体を残す(返す)必要があります。これが私の意味を理解するのに役立ちます。 –

関連する問題