Does the use of async/await create a new thread?

a 夏天 提交于 2019-11-26 08:06:21

问题


I am new to TPL and I am wondering: How does the asynchronous programming support that is new to C# 5.0 (via the new async and await keywords) relate to the creation of threads?

Specifically, does the use of async/await create a new thread each time that they are used? And if there many nested methods that use async/await, is a new thread created for each of those methods?


回答1:


In short NO

From Asynchronous Programming with Async and Await : Threads

The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active. You can use Task.Run to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available.




回答2:


So I've been reading up on the threading model, and Async / Await can certainly lead to new threads being used (not necessarily created - the pool creates them at application start). It's up to the scheduler to determine if a new thread is needed. And as I see it, a call to an awaitable function may have internal details that increase the chances of the scheduler utilizing another thread; simply because more work means more opportunities / reasons for the scheduler to divvy out work.

WinRT async operations automatically happen on the thread pool. And typically you will be calling FROM the thread pool, except for UI thread work .. Xaml/Input/Events.

Async operations started on Xaml/UI threads have their results delivered back to the [calling] UI thread. But asynchronous operation results started from a thread pool thread are delivered wherever the completion happens, which may not be the same thread you were on before. The reason behind this is that code written for the thread pool is likely to be written to be thread safe and it is also for efficiency, Windows doesn't have to negotiate that thread switch.

So again, in answer to the OP, new threads are not necessarily created but your application can and will use multiple threads to complete asynchronous work.

I know this seems to contradict some of the literature regarding async / await, but that's because although the async / await construct is not by itself multithreaded. Awaitables are the, or one of the mechanisms by which the scheduler can divide work and construct calls across threads.

This is at the limit of my knowledge right now regarding async and threading, so I might not have it exactly right, but I do think it's important to see the relationship between awaitables and threading.




回答3:


Sorry for being late to the party.

I am new to TPL and I am wondering: How does the asynchronous programming support that is new to C# 5.0 (via the new async and await keywords) relate to the creation of threads?

async/await is not introduced for thread creation, but to utilize the current thread optimally.

Your app might read files, wait for response from another server or even do a computation with high memory access (Simply any IO task). These tasks are not CPU intensive (Any task that will not use 100% of your thread).

Think about you are processing 1000 non CPU intensive tasks. In this case, process of creating 1000s of OS level thread might eatup more CPU and Memory than doing actual work on a single thread (4mb per thread in Windows, 4MB * 1000 = 4GB). At the same time if you run all the tasks sequencially, you might have to wait until the IO tasks gets finished. Which end up in long time to complete the task, while keeping the CPU idle.

Since we require parralallism to complete multiple tasks quickly, at the same time all parellal tasks are not CPU hungry, but creating threads is inefficient.

The compiler will break the execution at any method call to an async method (regardless of its being awaited or not) and immediatly execute the remaining code, once an await is reached, the execution will go inside the previous async. This will be repeated again and again untill all the async calls are completed and their awaiters are satisfied.

If any of the async method have heavy CPU load without a call to an async method, then yes, your system will become unresponsive and all the remaining async methods will not get called until the current task is finished.




回答4:


Using Async/Await doesn't necessarily cause a new thread to be created. But the use of Async/Await can lead to a new thread to be created because the awaitable function may internally spawn a new thread. And it often does, making the statement 'No, it doesn't spawn threads' almost useless in practice. For example, the following code spawns new threads.

VisualProcessor.Ctor()
{
    ...
    BuildAsync();
}

async void BuildAsync()
{
    ...
    TextureArray dudeTextures = await TextureArray.FromFilesAsync(…);
}

public static async Task<TextureArray> FromFilesAsync(...)
{    
    Debug.WriteLine("TextureArray.FromFilesAsync() T1 : Thread Id = " + GetCurrentThreadId());
    List<StorageFile> files = new List<StorageFile>();
    foreach (string path in paths)
    {
        if (path != null)
            files.Add(await Package.Current.InstalledLocation.GetFileAsync(path)); // << new threads
        else
            files.Add(null);
    }
    Debug.WriteLine("TextureArray.FromFilesAsync() T2 : Thread Id = " + GetCurrentThreadId());
    ...
}


来源:https://stackoverflow.com/questions/27265818/does-the-use-of-async-await-create-a-new-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!