2011-01-02 6 views
0

HTTPを使用してJSON RPCインターフェイス経由でXBMCと通信するためにC#で.NETライブラリをコーディングしています。C#async httpライブラリで大量のデリゲートとユーザーコールバックを管理する方法

私はpreliminary versionをコード化してリリースしましたが、すべてが同期して行われます。私はXBMC remote for WP7を構築していたので、私自身の目的のためにライブラリを非同期に記録しました。

私は今、新しい非同期ライブラリをリリースしたいと思いますが、私がする前にそれがきれいできちんとしていることを確認したいと思います。

非同期な性質のため、ユーザーはリクエストを開始し、代理人に一致するコールバックメソッドを提供し、受信後に応答を処理します。

問題は、ライブラリ内で要求の存続期間中のRequestStateオブジェクトを追跡し、http要求/応答とユーザーのコールバックなどがメンバー変数として含まれていることです。 1つのタイプのオブジェクトが戻ってきましたが、ユーザーが何を呼び出すかによって、曲のリストまたはムービーのリストなどが返されます。

私の実装では、単一のデリゲートResponseDataRecievedを使用しています。単純なオブジェクト - これは私によってのみ使用されるので、どのメソッドが何を返すのかを知っています。レスポンスを処理するとき、私は実際にそれを知っているタイプにオブジェクトをキャストします。リスト、リストなど

サードパーティはこれを行う必要はありません。 - デリゲートの署名に正しいタイプのオブジェクトが含まれている必要があります。だから私は第三者に返すことができるすべてのタイプの応答データの代理人が必要です - 具体的な問題は、どのように私は内部的にこれを正常に処理するのですか? - それぞれが異なるメンバー変数を持つ別々のRequestStateオブジェクトを持っていますか?異なる代表のために?それは正しいとは感じません。私はちょうどこれを優雅にそしてきれいにする方法を知らない。

答えて

0

あなたが正しく理解していれば、複数のメソッドを提供するインターフェイスがあります。これらのメソッドは、基本的に同じ種類のデリゲートを取りますが、入力とは異なるタイプのパラメータを取得します。このようなもの:

GetListOfSongs(..., delegate(List<Song> result) { ... }); 
GetListOfMovies(..., delegate(List<Movie> result) { ... }); 

あなたは、インターフェイスのメソッドと一緒にトリミングを開始するデリゲートの署名が心配ですか?

これが当てはまる場合、ジェネリックはあなたが探しているものです。実際、デリゲートのシグネチャが私の例と一致する場合(つまり、入力パラメータを1つ受け入れる場合)、値は返されません。これは、BCLに既に存在するデリゲート型です。それはAction<T>と呼ばれています。あなたはそのような上記の方法を宣言することができます:

GetListOfSongs(..., Action<List<Song>> callback); 
GetListOfMovies(..., Action<List<Movie>> callback); 

とあなたはまだだけでは、Action<T>で、シングルデリゲート型を持っていると思います。

ここで、複数のパラメータを渡す必要がある場合は、引き続き対象となります。最大16個の入力パラメータに対するアクションのバージョンが存在します(シグニチャは少し華やかに見えますが、Action<T1, T2, T3 ...>)。

インフラストラクチャ内のどこかで使用する値も返すようにする場合は、Func<T, TResult>はあなたの友人です(Tは入力パラメータの型、TResultは返される値の型です)。デリゲート)。

ボーナスとして、あなたのインターフェイスにList<T>を公開しないことをお勧めします。実際にすべてのクライアントでリスト操作が必要と思われる場合はIList<T>を使用しますが、ICollection<T>、またはIEnumerable<T>を考慮してください。

+0

ありがとうございました。私はまだ私のRequestStateオブジェクトにアクションを表現する方法について私の頭をラップするのに問題を抱えています。メンバー変数として宣言するときに型を提供する必要がありますが、実際には実行時までそれを知ることができません。私はpastebin'dいくつかの例のコードを私の問題をより明確に説明した。私はこれについてはあまりにもn00bではないことを願っています:( - http://pastebin.com/qjJgFPmV – Tyler

+0

私はあなたのコードを見て、これはジェネリック型パラメータのかなり重い伝播を参照してくださいように見える私は今仕事中ですが、後で詳しく調べる時間を見つけようとしています。その間に、誰かがそれを刺したければ、それに行きましょう:-) – Rytmis

+0

これは完全な例ではありません。私はあなたの完全なソースコードを持っていないので、間違ったことを推測しているかもしれません。ただし、XDataReceivedコールバックを、該当する場合は、のActionに置き換えました。 – Rytmis

0

まず、ジェネリックが考えられます。ResponseDataRecieved<T>ここで、Tはコールバックで予想される型です。ただし、コールバックはキャプチャされた変数として保存できます。例:

public delegate void CallBackA(int i); 
public delegate void CallBackB(string s); 

public class RequestHandler 
{ 
    public void QueueRequestA(CallBackA callback) 
    { 
     Task.Factory.StartNew(() => 
            { 
             int ret = 0; 
             //ret = get stuff of type A from server 
             callback(ret); //callback is captured here 
            }); 
    } 

    public void QueueRequestB(CallBackB callback) 
    { 
     Task.Factory.StartNew(() => 
            { 
             string str = ""; 
             //str = get stuff of typw B from server 
             callback(str); //callback is captured here 
            }); 
    } 
} 
関連する問題