2009-06-23 65 views
0

我有一个WCF Web服务,它目前搜索多个硬编码的dtSearch索引,然后合并返回给客户端的结果数据集。我有以下的C#代码:Genericising delegate/IAsyncResult calls

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委托类型是必需的:

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。我没有编译器的帮助就把它写下来,因此请小心输入错误。

+0

感谢您的回复,这很接近,但并不完美。这个理论很好,直到“tables.Add(iar.EndInvoke());” line - EndInvoke()是不是IAsyncResult的基本委托“sa”的方法。我用iar变量获得的最好结果是“IsCompleted”属性。 – asmorger 2009-06-23 20:17:00

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时出现无限循环的可能性...