Во-первых, я хочу отметить, что компонент COM может быть проблемой в зависимости от состояния его квартиры.Однопоточные квартирные объекты могут работать только в одном потоке.Существует автоматическая операция маршалинга, которая происходит с объектами STA, которая эффективно сериализует все вызовы к нему, поэтому, как бы вы ни старались, может не получить никакого распараллеливания.Даже если это был объект MTA, может возникнуть проблема с методом GetUser
, если он не предназначен для работы с потоками.
Но при условии, что ничего из этого не является проблемой 1 Я бы использовал ThreadPool
вместо того, чтобы создавать кучу потоков для этого.Вот как это может выглядеть.
public MyUser[] GetUsers(string appName, string[] names)
{
int count = 1; // Holds the number of pending work items.
var finished = new ManualResetEvent(false); // Used to wait for all work items to complete.
var users = new List<User>();
foreach (string user in names)
{
Interlocked.Increment(ref count); // Indicate that we have another work item.
ThreadPool.QueueUserWorkItem(
(state) =>
{
try
{
MembershipUser mu = this.ADAMProvider.GetUser(user, false);
if (mu != null)
{
lock (users)
{
users.Add(MyUser.CreateFrom(mu);
}
}
}
finally
{
// Signal the event if this is the last work item.
if (Interlocked.Decrement(ref count) == 0) finished.Set();
}
});
}
// Signal the event if this is the last work item.
if (Interlocked.Decrement(ref count) == 0) finished.Set();
// Wait for all work items to complete.
finished.WaitOne();
return users.ToArray();
}
Одна запутанная вещь в шаблоне, который я использовал выше, состоит в том, что он обрабатывает основной поток (тот, который помещает в очередь работу), как если бы это был другой рабочий элемент.Вот почему вы видите контрольный и сигнальный код в конце цикла.Без этого между вызовами Set
и WaitOne
может возникнуть очень тонкое состояние гонки.
Кстати, я должен отметить, что TPL доступен в .NET 3.5 как часть Reactive Extensions download.
1 Я подозреваю, что одна из двух упомянутых мной проблем будет в реальности.