Silverlight异步操作Foreach循环

时间:2011-11-24 12:54:27

标签: silverlight

我有一个查询以获取处方列表如下:

 var PRSCRPTSQuery = GV.dbContext.Load(GV.dbContext.GetPRSCRPTQuery(GV.curCustomer.CustCode,
                                          oOrdritemEdited.ProdCode, oOrdritemEdited.MedCode));
              PRSCRPTSQuery.Completed += new EventHandler(PRSCRPTSQuery_Completed);

在查询完成事件中,我有以下代码:

 void PRSCRPTSQuery_Completed(object sender, EventArgs e)
  {          
      lstPRSCRPT = GV.dbContext.PRSCRPTs.Where(p=>p.Status =="Activated").ToList();
      if (lstPRSCRPT.Count > 0)
      {
          foreach (var rec in lstPRSCRPT)
          {
               var OrderItemQuery = GV.dbContext.Load(GV.dbContext.GetOrdritemsQuery(rec.PresNo));
               OrderItemQuery.Completed += new EventHandler(OrderItemQuery_Completed);               
          }                            
      } 
  }       

列表lstPRSCRPT可以包含多个记录。我认为,foreach循环将前进到循环中的下一个项目,而不等待下面的OrderItemQuery_Completed事件:

  void OrderItemQuery_Completed(object sender, EventArgs e)
  {
      lstOrderItem = GV.dbContext.OrderItems.ToList();
      if (lstOrderItem.Count > 0)
      {
          foreach (var OrdrItemRec in lstOrderItem)
          {
              TotTonnes = (double)(TotTonnes + OrdrItemRec.Quantity);
          }              
      }
   }

这种情况有解决方法吗?我是SL

中异步编程类型的新手

2 个答案:

答案 0 :(得分:1)

我看到你来自哪里,当我第一次开始Silverlight编程的时候,我抓住了我对同步执行的先入之见,所以我知道当我完成调用查询时我有什么,而且我知道它确实在哪里出错了。

然而,Silverlight采用了这个概念并试图从你那里扯下来大喊“这种方式更好地信任我!”并且为了丰富客户端的交互性,它肯定会成功。这需要时间。您只需要了解更多关于如何将它们链接在一起的风格。

Faster Solutions之前显示的链接显示了C#在异步编码方面的作用,但知道它实际上为您做了什么是值得的。其中一些你已经掌握了你在问题中链接的代码。

当我遇到同样的情况时,你有背对背的异步回调是在我完成我正在做的事情时引发事件。例如:

public event EventHandler<EventArgs> LoadComplete;
public int QueryCount {get;set;}
public int QuerysCompleted {get;set;}

public void GetItems()
{
    var PRSCRPTSQuery = GV.dbContext.Load(GV.dbContext.GetPRSCRPTQuery
        (GV.curCustomer.CustCode, oOrdritemEdited.ProdCode, oOrdritemEdited.MedCode));
    PRSCRPTSQuery.Completed += new EventHandler(PRSCRPTSQuery_Completed);
    LoadComplete += loader_LoadComplete;
}


void PRSCRPTSQuery_Completed(object sender, EventArgs e)
{          
  lstPRSCRPT = GV.dbContext.PRSCRPTs.Where(p=>p.Status =="Activated").ToList();
  if (lstPRSCRPT.Count > 0)
  {
      QueryCount = lstPRSCRPT.Count;
      foreach (var rec in lstPRSCRPT)
      {
           var OrderItemQuery = GV.dbContext.Load(GV.dbContext.GetOrdritemsQuery(rec.PresNo));
           OrderItemQuery.Completed += new EventHandler(OrderItemQuery_Completed);               
      }                            
  } 

 }

  void OrderItemQuery_Completed(object sender, EventArgs e)
  {
      QueryCompleted++;
      lstOrderItem = GV.dbContext.OrderItems.ToList();
      if (lstOrderItem.Count > 0)
      {
          foreach (var OrdrItemRec in lstOrderItem)
          {
              TotTonnes = (double)(TotTonnes + OrdrItemRec.Quantity);
          }              
      }

     if(QueryCompleted == QueryCount)
     {
         RaiseLoadComplete();
     } 
  }



 public void RaiseLoadComplete()
 {
      if(LoadComplete != null)
      {
           LoadComplete(this, new EventArgs());
      }
 }


 void loader_LoadComplete(object sender, EventArgs e)
 {
      //Code to execute here
 }    

当我完成第一次查询要执行的代码时,我附加了一个事件。在第一个查询回调中,我初始化了我期待的响应数量。然后在第二个查询回调中我递增,直到我得到正确的金额,并调用事件说我完成。

这种方法唯一的注意事项是如果其中一个查询错误,最终的代码永远不会被执行。

答案 1 :(得分:0)

您可能会发现感兴趣的VS Async CTP。它引入了新的“async”关键字来处理异步事件。他是一个解释它的博客:VS Async