5

MSDNによるとasyncawait新しいスレッドを作成しないでください。

asyncandキーワードによって、追加のスレッドが作成されることはawaitありません。

これを念頭に置いて、いくつかの単純なプログラムの制御フローを理解するのに苦労しています。私の完全な例を以下に示します。NuGet からインストールできるDataflow ライブラリが必要であることに注意してください。

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

これは、タスクが完了すると、ループの実行Consume中に制御が与えられたことを示しているようです。forOutputAvailableAsync

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

これは、スレッド化されたモデルでは当然のことです。しかし、追加のスレッドが含まれていない場合、ループProduceの途中で制御を譲るにはどうすればよいでしょうか?for

4

2 に答える 2

2

追加のスレッドが含まれていない場合、for ループの途中で生成制御を生成するにはどうすればよいでしょうか?

追加のスレッドが含まれていないと誰が言ったのですか? あなたが述べた事実は:

async および await キーワードによって、追加のスレッドが作成されることはありません。

これは絶対に真実です。あなたのプログラムにはフラグメントが含まれています

target.Post(i);

await source.OutputAvailableAsync())

私の推測では、スレッドへの呼び出しtarget.Post(i)または作成が行われたと思われます。source.OutputAvailableAsync()awaitスレッドを生成しません。await呼び出しによって返されたタスクの継続としてメソッドの残りの部分を割り当て、呼び出し元に制御を返すだけです。そのタスクがその作業を行うスレッドを生成した場合、それはビジネスです。

await単なる別の制御フローです。確かに非常に複雑な制御フローですが、それでも制御フローです。スレッドを作成するための構文糖ではありません。これは、タスクに継続を割り当てるための構文糖衣です。

于 2013-05-21T21:58:35.443 に答える