Myślę, że jest inny i lepszy sposób podejścia do tego. (Przepraszam, jeśli przypadkowo Java-ize część składni)
Główny wątek tutaj ma listę rzeczy do zrobienia w "Zadaniach" - zamiast tworzyć wątki dla każdego zadania, co jest naprawdę nieefektywne, kiedy mieć tak wiele elementów, utworzyć żądaną liczbę wątków, a następnie poprosić ich o zadanie zadań z listy w razie potrzeby.
Pierwszą rzeczą do zrobienia jest dodanie zmiennej do klasy, z której pochodzi ten kod, do użycia jako wskaźnik na liście. Dodamy także jeden dla maksymalnej liczby oczekujących.
// New variable in your class definition
private int taskStackPointer;
private final static int MAX_THREADS = 5;
Utwórz metodę, która zwraca kolejne zadanie na liście i zwiększa wskaźnik stosu. Następnie należy utworzyć nowy interfejs dla tego:
// Make sure that only one thread has access at a time
[MethodImpl(MethodImplOptions.Synchronized)]
public task getNextTask()
{
if(taskStackPointer < tasks.Count)
return tasks[taskStackPointer++];
else
return null;
}
Naprzemiennie można powrócić zadania [taskStackPointer ++] kod, jeśli istnieje wartość można określić w ten sposób, „koniec listy”.. Prawdopodobnie jednak łatwiej to zrobić w ten sposób.
Interfejs:
public interface TaskDispatcher
{
[MethodImpl(MethodImplOptions.Synchronized)] public task getNextTask();
}
W klasie ReportGenerator zmień konstruktora zaakceptować dyspozytora obiektu:
public ReportGenerator(TaskDispatcher td, int idCode)
{
...
}
Trzeba także zmienić ReportGenerator klasę tak, że przetwarzanie ma zewnętrzną pętlę, która rozpoczyna się od wywołania td.getNextTask(), aby zażądać nowego zadania, i które kończy pętlę, gdy odzyskuje NULL.
Wreszcie zmieniać kod tworzenia wątku do czegoś takiego: (jest to po prostu daje wyobrażenie)
taskStackPointer = 0;
for (int i = 0; i < MAX_THREADS; i++)
{
ReportGenerator worker = new ReportGenerator(this,id);
worker.Go();
}
ten sposób można stworzyć żądaną liczbę wątków i zachować je wszystkie pracy w charakterze max .
(Nie jestem pewien, czy mam użycie "[MethodImpl (MethodImplOptions.Synchronized)]" dokładnie tak ...Jestem bardziej przyzwyczajony do Java niż C#)
Zweryfikowałeś wartość ** tasks.Count ** w debugerze? Czy próbowałeś zamiast tego wstawić "5"? –
Tablica zadań zawiera ~ 8000 obiektów. – Mike