我已经成功地击败了( :P )silverlight 中的异步怪物,如下所示:
var ctx = new ModelEntities(new Uri("http://localhost:2115/Data.svc"));
ManualResetEvent m1 = new ManualResetEvent(false);
ManualResetEvent m2 = new ManualResetEvent(false);
var q1 = (DataServiceQuery<Department>)(from e in ctx.Department select e);
var q2 = (DataServiceQuery<Person>)(from e in ctx.Person select e);
Department[] r1 = null;
Person[] r2 = null;
q1.BeginExecute(r =>
{
try { r1 = q1.EndExecute(r).ToArray(); }
finally { m1.Set(); }
}, null);
q2.BeginExecute(r =>
{
try { r2 = q2.EndExecute(r).ToArray(); }
finally { m2.Set(); }
}, null);
ThreadPool.QueueUserWorkItem((o) =>
{
WaitHandle.WaitAll(new WaitHandle[] { m1, m2 });
// do your thing..
});
基本的想法是产生一个服务员线程(最后一个块),它会引用等待对象。不要将您的 WaitAll 调用放在调用方方法/线程中,因为这将导致死锁,正如本网站或其他网站前面提到的其他人一样。
发生死锁是因为线程直到方法结束才开始,并且方法没有结束,因为 WaitAll 调用等待子线程结束。
但是,在我上面的情况下不是,因为 WaitAll 在另一个线程上。
PS:而不是 // do your thing 行放置代码,它使用 r1 和 r2 捕获的引用,如果结果失败,它将保存数据或 null。