0

現在、複数のハードコーディングされた dtSearch インデックスを検索し、結果のデータセットをマージしてクライアントに返す WCF Web サービスがあります。次の C# コードがあります。

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. 
    } 
}
4

2 に答える 2

0

さて、グーグルとあなたの非常に役立つリンクをさらに使用した後、これが私が今持っているものです:

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で無限ループが発生する可能性だけです...

于 2009-06-24T15:01:52.320 に答える
0

コードについて最初に注意すべきことは、必要なデリゲート タイプは 1 つだけであるということです。

delegate DataTabe SearchAsync(string term, int index);

これは、 SearchAll メソッドの が次のようになることを意味します。

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
}

あなたの新しいメソッドは、ある意味で一般的である必要はないと思います<T>。これが役立つことを願っています。

ps。これは、コンパイラの助けを借りずに頭のてっぺんから書き留めたので、タイプミスに注意してください。

于 2009-06-23T19:37:05.757 に答える