Assuming that I need to have some concurrent processes and I would like to forget about the old Thread
class and stick to Task
with an async pattern. Given the following codes:
// Scenario 1
public async Task Accept() {
while(true) {
Connection con = await connection.AcceptAsync();
await HandleConnection(con);
}
}
public Task HandleConnection(Connection con) {
// Long Running Logic
return Task.CompletedTask;
}
// Scenario 2
public async Task Accept() {
while(true) {
Connection con = await connection.AcceptAsync();
HandleConnection(con); // Produces a warning
}
}
public Task HandleConnection(Connection con) {
// Long Running Logic
return Task.CompletedTask;
}
Both these approaches fail and I cannot handle the connection concurrently. For example when the first connection is accepted then I cannot accept the second connection until the HandleConnection
method finishes its job. To solve this problem I can do the following:
public async Task Accept() {
while(true) {
Connection con = await connection.AcceptAsync();
HandleConnection(con); // Produces a warning
}
}
public Task HandleConnection(Connection con) {
return Task.Run(()=> {
//Long Running Logic
});
}
Now I am able to handle multiple connections but this behavior raises a few questions:
1- I heard that the await
keyword in contrast with wait
is non-blocking and in fact the whole async pattern in non-blocking as well. But in this situation it is actually blocking the parent thread.
2- When a method is async, a Task resembling that method must be generated as a result so that it can be awaited, is that true? if that is true then why is it blocking? else how does the await mechanism work?
3- If I don't await the Task, I get a compile time warning which says I have to await the task, but if I use it then the parent thread is blocked.
To ditch the warning I can do HandleConnection(con).Wait(0)
but isn't that a bad practice?