I create 2 methods that print x and y 100 times. I want them to run concurrent and I expect the output to be xxxxyxyxyyyxyyxyx... sthg like that. It doesn't print anything. Am I missing some logic here?
using System;
using System.Threading.Tasks;
namespace ConsoleApplication32
{
internal class Program
{
public static async Task<int> Print1()
{
await Task.Run(() =>
{
for (int i = 0; i < 100; i++)
{
Console.Write("x");
}
});
return 1;
}
public static async Task<int> Print2()
{
await Task.Run(() =>
{
for (int i = 0; i < 100; i++)
{
Console.Write("y");
}
});
return 1;
}
public static void Run()
{
Task<int> i = Print1();
Task<int> k = Print2();
}
private static void Main(string[] args)
{
Run();
}
}
}
Answer: Void main will be printed on the console.
To print a String to console output, you can use System. out. print() or System.
There are a couple things we need to tweak to get the desired output: xxxxyxyxyyyxyyxyx
.
The Run
method is not waiting for Task i
and Task k
to finish
Task
s completeConsole.ReadLine()
, it will prevent the console application from closing before the strings have been printed to the screen. Task.WhenAll
. Task.WhenAll
will allow the code yield to its calling thread (in this case, the Main Thread) which doesn't freeze the UI of the application, and allows the application to continue to print to the screen until the Task
s have completed. This may seem trivial for a simple console app, but it is crucial to never lock up the Main Thread when building any user-interactive application like mobile or web applications; locking up the Main Thread is what causing apps to "freeze".Task.WaitAll
. This is also bad practice because it will also freeze the application; Task.WaitAll
is not awaitable and cannot not yield to the calling thread. Print1()
and Print2()
never yield to the Main Thread
await
inside of the for loop
await
is necessary inside of the for loop
to allow CPU to continue executing the Main Thread, because Console.Write()
can only print to the screen on the Main Thread.using System;
using System.Threading.Tasks;
namespace ConsoleApplication32
{
internal class Program
{
public static async Task<int> Print1()
{
for (int i = 0; i < 100; i++)
{
Console.Write("x");
await Task.Delay(10);
}
return 1;
}
public static async Task<int> Print2()
{
for (int i = 0; i < 100; i++)
{
Console.Write("y");
await Task.Delay(10);
}
return 1;
}
public static async Task Run()
{
var i = Print1();
var k = Print2();
await Task.WhenAll(i, k);
}
private static void Main(string[] args)
{
Task.Run(async () => await Run()).GetAwaiter().GetResult();
}
}
}
xyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxxyxyxyxy Press any key to continue...
C# 7.1 introduces the ability to have an async Main
method. This means that we can tweak the Main
method as follows:
...
private static async Task Main(string[] args)
{
await Run();
}
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With