c# - 了解没有线程的异步/等待

标签 c# .net multithreading task-parallel-library async-await

<分区>

According to MSDN , asyncawait 不创建新线程:

The async and await keywords don't cause additional threads to be created.

考虑到这一点,我很难理解一些简单程序的控制流程。我的完整示例如下。请注意,它需要 Dataflow library ,您可以从 NuGet 安装它。

using System;
using System.Threading.Tasks.Dataflow;

namespace TaskSandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            BufferBlock<int> bufferBlock = new BufferBlock<int>();

            Consume(bufferBlock);
            Produce(bufferBlock);

            Console.ReadLine();
        }

        static bool touched;
        static void Produce(ITargetBlock<int> target)
        {
            for (int i = 0; i < 5; i++)
            {
                Console.Error.WriteLine("Producing " + i);
                target.Post(i);
                Console.Error.WriteLine("Performing intensive computation");
                touched = false;
                for (int j = 0; j < 100000000; j++)
                    ;
                Console.Error.WriteLine("Finished intensive computation. Touched: " + touched);
            }

            target.Complete();
        }

        static async void Consume(ISourceBlock<int> source)
        {
            while (await source.OutputAvailableAsync())
            {
                touched = true;
                int received = source.Receive();
                Console.Error.WriteLine("Received " + received);
            }
        }
    }
}

输出:

Producing 0
Performing intensive computation
Received 0
Finished intensive computation. Touched: True
Producing 1
Performing intensive computation
Received 1
Finished intensive computation. Touched: True
Producing 2
Performing intensive computation
Received 2
Finished intensive computation. Touched: False
Producing 3
Performing intensive computation
Received 3
Finished intensive computation. Touched: False
Producing 4
Performing intensive computation
Received 4
Finished intensive computation. Touched: True

这似乎表明 Consumefor 循环运行时获得控制权,因为 OutputAvailableAsync 任务完成:

for (int j = 0; j < 100000000; j++)
    ;

这在线程模型中不足为奇。但是,如果不涉及额外的线程,Produce 如何在 for 循环中间产生控制权?

最佳答案

if no additional threads are involved, how can Produce yield control in the middle of the for loop?

谁说不涉及额外的线程?您陈述的事实是:

The async and await keywords don't cause additional threads to be created.

这是绝对正确的。您的程序包含片段

target.Post(i);

await source.OutputAvailableAsync())

我的猜测是对 target.Post(i)source.OutputAvailableAsync() 的调用创建了一个线程。 await 不产生线程; await 所做的只是将方法的其余部分分配为调用返回的任务的延续,然后将控制权返回给调用者。如果该任务产生了一个线程来完成它的工作,那就是它的业务。

await 只是另一个控制流;可以肯定的是,这是一个非常复杂的控制流程,但仍然是一个控制流程。它不是创建线程的语法糖;它是为任务分配延续的语法糖。

关于c# - 了解没有线程的异步/等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16679173/

相关文章:

c# - 从从未 Hook 的事件中解开委托(delegate)是否有任何问题?

java - 仅当队列中有内容时才消耗 cpu 的工作线程

c++ - 如何使用线程安全函数将元素添加到数组?

java - 从新的 Runnable 类更新主线程

c# - Itextsharp : PDF size too large when including images

.net - 如何根据按下的行按钮获取数据网格wpf中的行索引

.net - 如何检查文件是否正在被另一个进程使用-Powershell

c# - 有没有办法在 C# 中实现平面文本框?

c# - org.xml.sax.SAXParseException : Character reference "&#x0" is an invalid XML character

c# - 从字符串中删除 HTML