Это можно сделать с помощью WaitHandle в IAsyncResult, возвращаемом каждым асинхронным методом.
Код прост. В Silverlight я просто делаю 10 сервисных вызовов, которые добавят элемент в ListBox. Я подожду, пока все вызовы службы не прекратятся, чтобы добавить еще одно сообщение в список (это должно выполняться в другом потоке, чтобы избежать блокировки пользовательского интерфейса). Также обратите внимание, что добавление элементов в список должно выполняться через диспетчер, так как они изменят пользовательский интерфейс. Есть куча лямд, но за ней легко следить.
public MainPage()
{
InitializeComponent();
var results = new ObservableCollection<string>();
var asyncResults = new List<IAsyncResult>();
resultsList.ItemsSource = results;
var service = new Service1Client() as Service1;
1.To(10).Do(i=>
asyncResults.Add(service.BeginDoWork(ar =>
Dispatcher.BeginInvoke(() => results.Add(String.Format("Call {0} finished: {1}", i, service.EndDoWork(ar)))),
null))
);
new Thread(()=>
{
asyncResults.ForEach(a => a.AsyncWaitHandle.WaitOne());
Dispatcher.BeginInvoke(() => results.Add("Everything finished"));
}).Start();
}
Просто чтобы помочь с тестированием, это услуга
public class Service1
{
private const int maxMilliSecs = 500;
private const int minMillisSecs = 100;
[OperationContract]
public int DoWork()
{
int millisSecsToWait = new Random().Next(maxMilliSecs - minMillisSecs) + minMillisSecs;
Thread.Sleep(millisSecsToWait);
return millisSecsToWait;
}
}