0

I have a program where I need to run a number of threads at the same time

int defaultMaxworkerThreads = 0;
int defaultmaxIOThreads = 0;
ThreadPool.GetMaxThreads(out defaultMaxworkerThreads, out defaultmaxIOThreads);
ThreadPool.SetMaxThreads(defaultMaxworkerThreads, defaultmaxIOThreads);

List<Data1> Data1 = PasswordFileHandler.ReadPasswordFile("Data1.txt");
List<Data1> Data2 = PasswordFileHandler.ReadPasswordFile("Data2.txt");
while (Data1.Count >= 0)
{

    List<String> Data1Subset = (from sub in Data1 select sub).Take(NumberOfWordPrThead).ToList();
   Data1 = _Data1.Except(Data1Subset ).ToList();
   _NumberOfTheadsRunning++;
   ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadCompleted), new TaskInfo(Data1Subset , Data2 ));
    //Start theads based on how many we like to start
}

How can I run more than 1 thread at a time? I would like to decide the number of threads at run-time, based on the number of cores and a config setting, but my code only seems to always run one one thread.

How should I change it to run on more than one thread?

Jannie Theunissen
  • 28,256
  • 21
  • 100
  • 127
  • It important to a callBack i dont need to wait it may that give me the probleam is there a better way to do this – user3265705 Apr 02 '14 at 18:29
  • Look into c# `async` or `parallel` – mituw16 Apr 02 '14 at 18:36
  • COnfigure minimum threads. Otherwise the thread pool will start low and slowly add moew threads when he needs them. Slowly. Use SetMinThreads to control that, not only max threads. But never do that on the system thread pool - what you do there can have serios side effects. – TomTom Apr 02 '14 at 18:38
  • 4
    and you could at least edit your code a little so we don't see that you're writing a password cracker app :) – John Gardner Apr 02 '14 at 18:38

1 Answers1

1

As @TomTom pointed out, your code will work properly if you set both SetMinThreads and SetMaxThreads. In accordance with MSDN you also have to watch out not to quit the main thread too early, before the execution of the ThreadPool:

// used to simulate different work time
static Random random = new Random();
// worker
static private void callback(Object data) 
{
   Console.WriteLine(String.Format("Called from {0}", data));
   System.Threading.Thread.Sleep(random.Next(100, 1000));
}
//
int minWorker, minIOC;
ThreadPool.GetMinThreads(out minWorker, out minIOC);
ThreadPool.SetMaxThreads(5, minIOC);
ThreadPool.SetMinThreads(3, minIOC);
for(int i = 0; i < 3; i++)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(callback), i.ToString());
}
// give the ThreadPool a change to run
Thread.Sleep(1000);

A good alternative to the standard ThreadPool is the Task Parallel Library which introduces the concept of Tasks. Using the Task object you could for example easily start multiple tasks like this:

// global variable
Random random = new Random(); // used to simulate different work time

// unit of work
private void callback(int i)
{
    Console.WriteLine(String.Format("Nr. {0}", i));
    System.Threading.Thread.Sleep(random.Next(100, 1000));
}   

const int max = 5;
var tasks = new System.Threading.Tasks.Task[max];
for (int i = 0; i < max; i++)
{
    var copy = i;
    // create the tasks and init the work units
    tasks[i] = new System.Threading.Tasks.Task(() => callback(copy));
}
// start the parallel execution
foreach (var task in tasks)
{
    task.Start();
}
// optionally wait for all tasks to finish
System.Threading.Tasks.Task.WaitAll(tasks);

You could also start the code execution immediately using Task.Factory like this:

const int max = 5;
var tasks = new System.Threading.Tasks.Task[max];
for (int i = 0; i < max; i++)
{
    var copy = i;
    // start execution immediately
    tasks[i] = System.Threading.Tasks.Task.Factory.StartNew(() => callback(copy));
}
System.Threading.Tasks.Task.WaitAll(tasks);

Have a look at this SO post to see the difference between ThreadPool.QueueUserWorkItem vs. Task.Factory.StartNew.

Community
  • 1
  • 1
keenthinker
  • 7,645
  • 2
  • 35
  • 45