Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
150 views
in Technique[技术] by (71.8m points)

c# - Async-Await thread behavior and questions

What is the use of an async await method that only call one liners async await methods? How many threads do they span? How much CPU you can end up consuming? Hi, lately I'm seeing a lot of methods using the async and await keywords. I still cannot wrap my head around the use of them and the underlying behavior as well as their advantage when applied like below. I ahve also obseved a problem with the CPU (going 100%) when they use it for everything and I'm seeing thread.run as the culprit for cpu utilization for some of this cases.

myController.cs

[HttpPost]

[ProducesResponseType(body)]

public async Task<IActionResult> Post([FromBody]Body body){

_MyClassService.sendMessage(body);

return Ok(body);

}

My Service class

Myclass.cs

private async void sendMessage(){

await SendToProperChannel();

}



private async Task SendToProperChannel(){

await DoWorkInProperChannel();

}



private Task<int> DoWorkInProperChannel(){

await SomethingThatTakes5Seconds();

return 1+1;

}

According to my little knowledge.

We are making the controller request async in order to not block main threads, allowing to receive higher throughput at the controller level.

We are making also all the functions async to not block the upper threads that call those methods.

I also understand that since we have so many awaits, everyone returns a task but also a thread is handling that work waiting for the completion of this.

I'm still not clear on the thread number but I believe we are spawning more than 1 thread to fulfill a single request.

My questions.

What is the use of having one liners await if the upper method cannot continue without the response? The API can, in fact, receive more throughput, but down from there everything will be kind of sync, also spawning more threads just for jumping between methods in my class doesn't seem healthy.

If I only awaiting on one liners, in this specific code, the result would not be the same as removing the awaits?

All methods will also handle more throughput, since they don't block, but will also spawn more threads?

How is the syntax for starting an async method and waiting for the response way down inside the same method.

Example:

private async Task<int> myAsyncWorkerMethod(){

var myNeededValue=methodThatINeed();

var mySecondValue=methodWithSecondValue();

await myNeededValue;

await mySecondValue;

return myNeededValue+mySecondValue;

}

What is the benefit from async and await against having just a thread pool that handles all downstream calls, which you can easily control its size and can easily detect thread starvation and queue depth? (I might be using some java terms in here that might not apply)

Thoughts

In other lenguages I have seen the repercussions of thread context change, if your CPU is not powerful enough or you have thread starvation because of the thread pool size, does this .net uncontrolled thread pool would not have the same repercussions and just use the CPU as much as he wants?

You don't need to create an async invocation if you need them to return the response for the await statement. making asynchronous is only needed when you need to do some work on the above method?

Even if you are awaiting method results from another class unless you don't want to block the main thread you should also not wait for it.

Thanks in advance

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'll try to answer your points and questions all at once:

"We are making the controller request async in order to not block main threads, allowing to receive higher throughput at the controller level."

No, that's completely incorrect. Turn on proper compiler exceptions and you will see that using async without await is a waste of time that gives you no value and generates useless IL code.

"I also understand that since we have so many awaits, everyone returns a task but also a thread is handling that work waiting for the completion of this."

There is no thread

"I'm still not clear on the thread number but I believe we are spawning more than 1 thread to fulfill a single request."

As mentioned above, that is invalid as well.

What is the use of having one liners await if the upper method cannot continue without the response?

Basically none, the code could have been just:

private async void sendMessage()
{    
    await DoWorkInProperChannel();
}

private Task<int> DoWorkInProperChannel()
{
    // `await Thread.Sleep()` is not valid, `Sleep` returns `void` 
    await Task.Delay(1000);

    return 1+1;
}

Note: not a single new thread is created from the code above; not in the original version or in mine.

If I only awaiting on one liners, in this specific code, the result would not be the same as removing the awaits?

Not at all, you would need to return the Task generated for the code to be the same. Except, of course, in the case of the async void method, where you cannot return anything.

private async Task<int> myAsyncWorkerMethod()
{
    var myNeededValue=methodThatINeed();
    var mySecondValue=methodWithSecondValue();
    await myNeededValue;
    await mySecondValue;

    return myNeededValue+mySecondValue;
}

This is known as parallel asynchronous code and it has nothing to do with the previous example. Whether you can use parallel code or not depends on what you are doing.

In other languages I have seen the repercussions of thread context change, if your CPU is not powerful enough or you have thread starvation because of the thread pool size, does this .net uncontrolled thread pool would not have the same repercussions and just use the CPU as much as he wants?

There is not a single context change in the code you posted, so this is not relevant.

Even if you are awaiting method results from another class unless you don't want to block the main thread you should also not wait for it.

You are using ASP.NET Core, there's no main thread.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...