我有一个查询以获取处方列表如下:
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
中异步编程类型的新手答案 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