Да, есть.
Предлагаемый подход
1) счетчик и ручка ожидания
int ActiveCount = 1; // 1 (!) is important
EventWaitHandle ewhAllDone = new EventWaitHandle(false, ResetMode.Manual);
2) добавление цикла
foreach (string someString in arrayStrings)
{
Interlocked.Increment(ref ActiveCount);
ThreadPool.QueueUserWorkItem(this.DoSomething, someString);
// Thread.Sleep(100); // you really need this sleep ?
}
PostActionCheck();
ewhAllDone.Wait();
3) DoSomething
должно выглядеть как
{
try
{
// some long executing code
}
finally
{
// ....
PostActionCheck();
}
}
4) где PostActionCheck
равно
void PostActionCheck()
{
if (Interlocked.Decrement(ref ActiveCount) == 0)
ewhAllDone.Set();
}
Идея
ActiveCount инициализируется с помощью 1
, а затем увеличивается * в 1022 * раз.
PostActionCheck
вызывается n + 1
раз. Последний вызовет событие.
Преимущество этого решения состоит в том, что он использует один объект ядра (который является событием) и 2 * n + 1
вызовы легких API. (Может быть меньше?)
приписка
Я написал здесь код, возможно, я неправильно написал некоторые имена классов.