Чтобы иметь возможность успешно реализовать шаблон, который вы описываете, вы должны иметь возможность вызвать обратный вызов, переданный в ваш метод BeginMultipleActions
после завершения всех отдельных действий.Использование событий и ожидание их может победить вашу единственную цель - выполнять асинхронные вызовы, поскольку они блокируют потоки.Обратный вызов, который вы передаете в одно действие, должен быть в состоянии выяснить, когда все методы будут завершены, а затем вызвать обратный вызов, предоставленный вашим клиентом для метода BeginMultipleActions
.Вот пример, который может сделать это для вас (я не проверял это).Тем не менее, это только для начала и далеко не идеально.Будет несколько нюансов, через которые вам придется проработать.
interface ILibrary
{
IAsyncResult BeginAction(string name, AsyncCallback callback, object state);
int EndAction(IAsyncResult asyncResult, out object state);
}
class Manager
{
private ILibrary library;
class AsyncCallInfo : IAsyncResult
{
public int PendingOps;
public AsyncCallback Callback { get; set; }
public object AsyncState { get; set; }
public WaitHandle AsyncWaitHandle
{
// Implement this if needed
get { throw new NotImplementedException(); }
}
public bool CompletedSynchronously
{
get { return false; }
}
public bool IsCompleted
{
get { return PendingOps == 0; }
}
}
public IAsyncResult BeginMultipleActions(IEnumerable<string> names,
AsyncCallback callback, object state)
{
var callInfo = new AsyncCallInfo {
Callback = callback,
AsyncState = state
};
callInfo.PendingOps = names.Count();
foreach (string name in names)
{
library.BeginAction(name, ar => OnSingleActionCompleted(ar, callInfo), null);
}
return callInfo;
}
public int EndMultipleActions(IAsyncResult asyncResult, out object state)
{
// do your stuff
state = asyncResult.AsyncState;
return 0;
}
private void OnSingleActionCompleted(IAsyncResult asyncResult, AsyncCallInfo callInfo)
{
//???
Interlocked.Decrement(ref callInfo.PendingOps);
if (callInfo.PendingOps == 0)
{
callInfo.Callback(callInfo);
}
}
}
Предлагаю вам взглянуть на AsyncEnumerator Джеффри Рихтера.Это упрощает написание асинхронного кода и поддерживает несколько шаблонов асинхронных реализаций - http://msdn.microsoft.com/en-us/magazine/cc546608.aspx