Обобщение делегатов / вызовов IAsyncResult - PullRequest
0 голосов
/ 23 июня 2009

У меня есть веб-служба WCF, которая в настоящее время ищет несколько жестко закодированных индексов dtSearch, а затем объединяет полученные наборы данных для возврата клиенту. У меня есть следующий код 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
    }
}

Мой вопрос: каков наилучший способ переместить эту логику в отдельный общий класс и сделать это для объектов List из 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. 
    } 
}

Ответы [ 2 ]

0 голосов
/ 24 июня 2009

Хорошо, после дальнейшего использования Google и вашей очень полезной ссылки, вот что у меня сейчас:

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

0 голосов
/ 23 июня 2009

Первое, что следует отметить в вашем коде, это то, что требуется только 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>. Надеюсь, это поможет.

пс. Я записал это с головы без помощи компилятора, поэтому, пожалуйста, остерегайтесь опечаток.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...