I'm reviewing Multithreading and I'm (redundancy) testing ways to use tasks, I made a static class for testing,
static class PruebaTask
{
public static void usoTasks()
{
DateTime Inicio = DateTime.Now;
Task task;
for (int i = 0; i < 5000000; i++)
{
task = new Task(() => metodoPrueba());
//task = Task.Run(() => metodoPrueba());//así no requiere instancia
}
MessageBox.Show("El task Tardó" + (DateTime.Now - Inicio)+ " thread: " + Thread.CurrentThread.ManagedThreadId);
}
static void metodoPrueba()
{
double d = 0;
for (int j = 0; j < 10000; j++)
{
d = 12445 / 434 * 495 / 3.09;
}
}
}
And I call from here
private void button1_Click(object sender, EventArgs e)
{
//PruebaThread.usoThreads();
PruebaTask.usoTasks();
//PruebaBox.probarMsg();
}
My question is:
What is the difference between these 2 sentences:
task = new Task(() => metodoPrueba());
task = Task.Run(() => metodoPrueba());
the second can also be left alone as:
Task.Run(() => metodoPrueba());
It returns a Task so I can assign it to a Task variable, but in the end the result is the same
what I see is that when using it task = new Task(() => metodoPrueba());
it takes a wonderful amount of o.3 seconds, instead Task.Run(() => metodoPrueba());
it takes practically 1 minute, and it is doing it 5 million times.
The difference is obvious, but does anyone know why this happens?
(I'm just getting started in C#, I haven't started with await or async yet, I've also tried with new instances of Threads directly, and it still takes a long time, there, I understand that it hits performance when creating new threads, and instead, the Tasks are optimizations to use already existing Threads, if I'm wrong correct me)
new Task(...)
is the option that gives you full control of how and when it runs, you get a reference to the task but it doesn't run until you tell it to by calling theStart
. It is not recommended to use this option unless it is necessary, calling separatelyStart
has a performance cost.Task.Factory.StartNew()
It is used to create and schedule the execution of the task in a single method. It receives the same parameters, has the same overloads as the constructor, and as you already realized it is equivalent (but without any performance impact) to:Task.Run
is the most recommended option and is equivalent to callingTask.Factory.StartNew()
with parameters that are different from the default behavior but are desirable in most scenarios: