2009-06-23 3 views
0

現在、複数のハードコードされたdtSearchインデックスを検索し、結果のデータセットをマージしてクライアントに返すWCF Webサービスがあります。私は、次のC#のコードを持っている:代理人/ IAsyncResult呼び出しの生成

public class Search : ISearch 
{ 
    delegate DataTable PDelegate(string term, int cid); 
    delegate DataTable CDelegate(string term, int sid); 

    public DataTable SearchPIndex(string term, int cid) {/* do search */} 
    public DataTable SearchCIndex(string term, int sid) {/* do search */} 

    public DataTable SearchAll(string term, int cid, int sid) 
    { 
     PDelegate pDel = new PDelegate(SearchPIndex); 
     CDelegate cDel = new CDelegate(SearchCIndex); 

     IAsyncResult pInvoke = pDel.BeginInvoke(term, cid, null, null); 
     IAsyncResult cInvoke = cDel.BeginInvoke(temr, sid, null, null); 

     DataTable pResults = pdel.EndInvoke(pInvoke); 
     DataTable cResults = cdel.EndInvoke(cInvoke); 

     // combine the DataTables and return them 
    } 
} 

私の質問は:独立した、一般的なクラスにこのロジックを移動し、1つの... n個のオブジェクトのリストのためにこれを行うための最善の方法は何ですか?

私は、SearchPIndexメソッドとSearchCIndexメソッドを置き換えるすべての物理的な検索を実行する汎用オブジェクトを作成しましたが、代理/ IAsyncResult呼び出しを汎用オブジェクトに統合する方法は不明です。

私はこれに従うことができるベストプラクティスはありますか?


編集:申し訳ありませんが...サイト上の「使用者」として初めて...「答えは」上「のコメント」よりも、このためのより良い場所のように思えます。

私はそれを試してみるつもりですが、この方法ではうまくいくのでしょうか?あなたのコードについて注意すべき

SearchAsync sa = new SearchAsync(SearchIndex); 
var asyncs = new List<IAsyncResult>(); 

foreach(int index in indices) 
{ 
    asyncs.Add(sa.BeginInvoke(term, index, null, null)); 
} 

var tables = new List<DataTable>(); 
foreach(IAsyncResult iar in asyncs) 
{ 
    try 
    { 
     tables.Add(sa.EndInvoke(iar)); 
    } 
    catch 
    { 
     //etc. 
    } 
} 

答えて

0

まず最初はわずか1デリゲート型が必要とされることである。

public DataTable SearchAll(string term, List<int> indices) 
{ 
    var asyncs = new List<IAsyncResult>(); 
    foreach(int index in indices) 
    { 
     SearchAsync sa = new SearchAsync(NewMethodSearchWithTermAndIndexParemeter); 
     asyncs.Add(sa.BeginInvoke(term, index, null, null)); 
    } 
    var tables = new List<DataTable>(); 
    foreach(IAsyncResult iar in asyncs) 
    { 
     try 
     { 
       tables.Add(sa.EndInvoke(iar)); 
     } 
     catch 
     { 
      ...appropriately handle 
     } 
    } 
    .... merge tables 
} 

I:

delegate DataTabe SearchAsync(string term, int index); 

これは、検索searchall方法のような何か良いことを意味します新しい方法が<T>の意味では一般的である必要があるとは思わないでください。私はこれが役立つことを願っています

ps。私はコンパイラの助けを借りずに頭の上からこれを書きましたので、誤植に注意してください。

+0

返事ありがとうございます、これは近いですが、これはうまくいきません。この理論は "tables.Add(iar.EndInvoke());まで有効です。 line - EndInvoke()は、IAsyncResultではなく、ベースデリゲート "sa"のメソッドです。 iar変数で得られる最良のものは、 "IsCompleted"プロパティです。 – asmorger

+0

上記のコードは素晴らしいようですが、EndInvokeが順番に実行され、ブロックされているという事実は、これを非同期にすることによってパフォーマンスを改善するという非常に良い例にはなりません。おそらくここでAsyncCallBackを使用したいと思うでしょう:http://msdn.microsoft.com/en-us/library/2e08f6yc(VS.71).aspx –

0

OK]をクリックして、グーグルのさらなる使用して、非常に参考にリンクした後、ここで私が今持っているものです。

public class Search : ISearch 
{ 
    delegate DataTable SearchAsync(int stypeid, string term, int? cid, int? sid); 
    List<DataTable> tables; 

    private void ProcessCallBack(IAsyncResult result) 
    { 
     AsyncResult asyncResult = (AsyncResult)result; 
     SearchAsync async = (SearchAsync)asyncResult.AsyncDelegate; 

     if(tables == null) 
     { 
      tables = new List<DataTable>(); 
     } 

     try 
     { 
      tables.Add(async.EndInvoke(result)); 
     } 
     catch(Exception ex) 
     { 
      /* handle error */ 
      tables.Add(null); 
     } 
    } 

    public DataTable SearchIndex(int stypeid, string term, int? cid, int? sid) 
    {/* do search */} 

    public DataTable SerachGlobal(string term, int? cid, int? sid) 
    { 
     List<SearchTypes> types ...; /* load types from db */ 
     SearchAsync async = new SearchAsync(SearchIndex); 
     AsyncCallback callBack = new AsyncCallback(ProcessCallBack); 

     foreach(SearchType t in types) 
     { 
      async.BeginInvoke(t.searchtypeid, term, cid, sid, callBack, null); 
     } 

     do 
     { 
      Thread.Sleep(100); 
     } 
     while(tables == null || tables.Count < types.Count); 

     /* combine the tables */ 

    } 
} 

は、これはどのように見えますか? 私に関係する唯一の事は、do/whileの無限ループの可能性です。

関連する問題