When are threads (Thread Pool) initialized? - W#

2

I have the following code:

public void mainFunc()   {
    for (int i = 0; i < 10; i++)
    { 
        ThreadPool.QueueUserWorkItem(new WaitCallback(funcThread), pto);
    }
    Thread.Sleep(2000) // Thread de teste.
    // Fazer algo quando todas as funcThread chegarem ao fim.
    // .....
    // Form4.doSomething()
}

That is, I want funcThread to be created 10 times and after all 10 functions come to an end, I want to do a routine that calls another Form. What happens is that first it executes everything that is in mainFunc and only after it does what is in threads .

I've tried putting a% of% 2 seconds, but not like that. It lets pass the two seconds, does what it has to do in form4 and only then advances to the 10 threads ...

Why is it that as soon as I do Thread.Sleep the program does not start running the threads right away, but only after finishing mainFunc? Thanks

    
asked by anonymous 09.02.2016 / 20:11

1 answer

2

When it comes to manipulating threads in C #, we recommend that you use the Task Parallel Library (TPL) , which is a higher-level API for manipulating the application's ThreadPool. And neither am I saying that: Microsoft itself recommends because they realized how complicated it was to control some things through the original library:

  

In conclusion, I'll reiterate what the CLR team's ThreadPool developer has already stated:

     

"Task is now the preferred way to queue work to the thread pool."

Anyway, when using a QueueUserWorkItem , you are suggesting that when there is some Thread left, it will execute a certain method. The problem is that in this way, we have no control over when this will occur.

Through TPL, we basically have the Task class that represents an asynchronous operation that may or may not have been done yet. So, in the example below, I have TPL run 10 times an operation and I keep the Tasks reference to control its executions:

// utilizei um clique de botão só para testar, tanto faz aqui
private async void button1_Click(object sender, EventArgs e)
{
    // só porque você definia ele como parâmetro do seu método
    int pto = 0;

    var taskList = new List<Task>();

    for (int i = 0; i < 10; i++)
    {
        // manda enfileirar no ThreadPool pra executar o seu método
        var task = Task.Run(() => { funcThread(pto); });

        // adiciona na lista a referência a cada Task criada
        taskList.Add(task);
    }

    // manda esperar que todas as Tasks referenciadas terminem para que o programa continue
    Task.WaitAll(taskList.ToArray());

    // espera uns 5 segundos só pra vermos o output confirmar o teste
    await Task.Delay(5000);

    // chama o seu form sem problemas
    Console.WriteLine(String.Format("{0} - Form4.doSomething()", DateTime.Now));
}

public void funcThread(int pto)
{
    Console.WriteLine(String.Format("{0} - funcThread", DateTime.Now));
}

The output from my example:

09/02/2016 23:48:55 - funcThread
09/02/2016 23:48:55 - funcThread
09/02/2016 23:48:55 - funcThread
09/02/2016 23:48:55 - funcThread
09/02/2016 23:48:55 - funcThread
09/02/2016 23:48:55 - funcThread
09/02/2016 23:48:55 - funcThread
09/02/2016 23:48:55 - funcThread
09/02/2016 23:48:55 - funcThread
09/02/2016 23:48:55 - funcThread
09/02/2016 23:49:00 - Form4.doSomething()

Note : I only used async / await in the method to hold for 5 minutes, it is not really necessary for your method to be marked as asynchronous to the Task.WaitAll () work

    
10.02.2016 / 03:05