C# – Genericising delegate/IAsyncResult calls

c++delegatesiasyncresult

I have a WCF web service that currently searches multiple, hard-coded dtSearch indices and then merges the resulting datasets to be returned back to the client. I have the following C# code:

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

My question is: what is the best way to move this logic into a separate, generic class and do this for a List of 1…n objects?

I have a generic object that I have created that now performs all the physical searching (replacing the SearchPIndex and SearchCIndex methods), but I am uncertain as how I can integrate the delegate/IAsyncResult calls into the generic.

Is there a best-practice I can follow for this?


EDIT: Sorry… first time as a "user" on the site … an "answer" seems like a better place for this than the "comment" above.

I'm going to play with it, but would this work within the method?

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

Best Solution

First thing to note about your code is that only 1 delegate type is required:

delegate DataTabe SearchAsync(string term, int index);

This means that the of SearchAll method can be something like:

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 don't think your new method needs to be generic in the <T> sense. I hope this helps.

ps. I wrote this down off the top off my head without the aid of the compiler so please beware of the typos.

Related Question