Текущая реализация: ожидается, что значения собираются parallelCount
, использует ThreadPool
для обработки значений, до тех пор, пока все потоки не завершатся, не заберут еще один набор значений и так далее ...C# - Передача данных обратно из ThreadPool в главную нить
Код:
private static int parallelCount = 5;
private int taskIndex;
private object[] paramObjects;
// Each ThreadPool thread should access only one item of the array,
// release object when done, to be used by another thread
private object[] reusableObjects = new object[parallelCount];
private void MultiThreadedGenerate(object paramObject)
{
paramObjects[taskIndex] = paramObject;
taskIndex++;
if (taskIndex == parallelCount)
{
MultiThreadedGenerate();
// Reset
taskIndex = 0;
}
}
/*
* Called when 'paramObjects' array gets filled
*/
private void MultiThreadedGenerate()
{
int remainingToGenerate = paramObjects.Count;
resetEvent.Reset();
for (int i = 0; i < paramObjects.Count; i++)
{
ThreadPool.QueueUserWorkItem(delegate(object obj)
{
try
{
int currentIndex = (int) obj;
Generate(currentIndex, paramObjects[currentIndex], reusableObjects[currentIndex]);
}
finally
{
if (Interlocked.Decrement(ref remainingToGenerate) == 0)
{
resetEvent.Set();
}
}
}, i);
}
resetEvent.WaitOne();
}
Я видел значительные улучшения производительности при таком подходе, однако существует целый ряд вопросов, рассмотреть следующие вопросы:
[1] Сбор значений в paramObjects
и синхронизации с использованием resetEvent
можно избежать, так как нет зависимости между потоками (или текущим набором значений со следующим набором значений). Я делаю это только для управления доступом к reusableObjects
(когда выполняется обработка paramObjects
, я знаю, что все объекты в reusableObjects являются бесплатными, поэтому taskIndex
сбрасывается, и каждая новая задача следующего набора значений будет иметь свой уникальный «reusableObj ' работать с).
[2] Не существует реального соединения между размером reusableObjects
и количеством потоков, используемых ThreadPool
. Я мог бы инициализировать reusableObjects
, чтобы иметь 10 объектов и сказать из-за некоторых ограничений, ThreadPool может запускать только 3 потока для моего метода MultiThreadedGenerate()
, тогда я теряю память.
Так, избавившись от paramObjects
, как можно выше код будет уточнена таким образом, что как только один поток завершает свою работу, что нить возвращает его taskIndex
(или reusableObj
) не используется и больше не нуждается, так что это становится доступным для следующего значения. Кроме того, код должен создать reUsableObject
и добавить его в некоторую коллекцию только тогда, когда есть спрос на нее. Является ли использование очереди здесь хорошей идеей?
спасибо.
Какая версия .Net вы? –
Я использую .NET 3.5 – alhazen