1283

私の理解では、asyncandawaitが行う主なことの 1 つは、コードを読みやすくすることです。

現在、最も基本的な例を試しています。コメントをインラインで追加しました。私のためにそれを明確にすることができますか?

// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
    Task<int> access = DoSomethingAsync();
    // task independent stuff here

    // this line is reached after the 5 seconds sleep from 
    // DoSomethingAsync() method. Shouldn't it be reached immediately? 
    int a = 1; 

    // from my understanding the waiting should be done here.
    int x = await access; 
}

async Task<int> DoSomethingAsync()
{
    // is this executed on a background thread?
    System.Threading.Thread.Sleep(5000);
    return 1;
}
4

24 に答える 24

886

を使用するasyncawait、コンパイラはバックグラウンドでステート マシンを生成します。

これは、進行中の高レベルの詳細のいくつかを説明できることを願っている例です。

public async Task MyMethodAsync()
{
    Task<int> longRunningTask = LongRunningOperationAsync();
    // independent work which doesn't need the result of LongRunningOperationAsync can be done here

    //and now we call await on the task 
    int result = await longRunningTask;
    //use the result 
    Console.WriteLine(result);
}

public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation 
{
    await Task.Delay(1000); // 1 second delay
    return 1;
}

さて、ここで何が起こるか:

  1. Task<int> longRunningTask = LongRunningOperationAsync();実行を開始しますLongRunningOperation

  2. await longRunningTaskメイン スレッド (スレッド ID = 1) に到達したと仮定して、独立した作業が行われます。

    longRunningTaskが終了せず、まだ実行中の場合は、MyMethodAsync()呼び出し元のメソッドに戻るため、メイン スレッドはブロックされません。これlongRunningTaskが完了すると、ThreadPool からのスレッド (任意のスレッドである可能性があります) が以前のコンテキストに戻り、MyMethodAsync()実行を継続します (この場合、コンソールに結果を出力します)。

2 番目のケースは、longRunningTaskがすでに実行を終了しており、結果が利用可能である場合です。に到達するawait longRunningTaskと、すでに結果が得られているため、コードはまったく同じスレッドで実行され続けます。(この場合、結果をコンソールに出力します)。もちろん、これは がTask.Delay(1000)関与する上記の例には当てはまりません。

于 2013-11-14T18:55:19.103 に答える
207

私の理解では、async と await が行う主なことの 1 つは、コードを読みやすくすることです。

非同期コードを読みやすく書きやすくするためのものです。

長時間のロジックを実行するためにバックグラウンド スレッドを生成するのと同じことですか?

全くない。

// このメソッドを「async」としてマークする必要がある理由がわかりません。

キーワードは、asyncキーワードを有効にしawaitます。したがって、使用するメソッドはすべてawaitマークする必要がありますasync

// DoSomethingAsync() メソッドからの 5 秒間のスリープ後に、この行に到達します。すぐに届くのではないですか?

いいえ、asyncデフォルトではメソッドは別のスレッドで実行されないためです。

// これはバックグラウンド スレッドで実行されますか?

いいえ。


私のasync/awaitイントロが役に立つかもしれません。MSDNの公式ドキュメントも非常に優れており (特にTAPセクション)、asyncチームは優れたFAQを公開しています。

于 2013-01-22T13:17:40.580 に答える
199

説明

async/の簡単な例をawait高レベルで示します。これ以外にも考慮すべき詳細がたくさんあります。

注: Task.Delay(1000)1 秒間の作業をシミュレートします。これは、外部リソースからの応答を待っていると考えてください。私たちのコードは応答を待っているので、システムは実行中のタスクを脇に置き、終了したら戻ってくることができます。その間、そのスレッドで他の作業を行うことができます。

以下の例では、最初のブロックがまさにそれを行っています。すべてのタスク (Task.Delay行) をすぐに開始し、脇に置きます。コードはawait a、次の行に進む前に 1 秒の遅延が完了するまで、その行で一時停止します。、bcdおよびeすべてが (await がないため) とほぼ同時に実行を開始しaたため、この場合はほぼ同時に終了するはずです。

以下の例では、2 番目のブロックがタスクを開始し、それが終了するのを待ってから (つまりawait、後続のタスクを開始します)。これの各反復には 1 秒かかります。はawaitプログラムを一時停止し、続行する前に結果を待っています。これが、最初のブロックと 2 番目のブロックの主な違いです。

Console.WriteLine(DateTime.Now);

// This block takes 1 second to run because all
// 5 tasks are running simultaneously
{
    var a = Task.Delay(1000);
    var b = Task.Delay(1000);
    var c = Task.Delay(1000);
    var d = Task.Delay(1000);
    var e = Task.Delay(1000);

    await a;
    await b;
    await c;
    await d;
    await e;
}

Console.WriteLine(DateTime.Now);

// This block takes 5 seconds to run because each "await"
// pauses the code until the task finishes
{
    await Task.Delay(1000);
    await Task.Delay(1000);
    await Task.Delay(1000);
    await Task.Delay(1000);
    await Task.Delay(1000);
}
Console.WriteLine(DateTime.Now);

出力:

5/24/2017 2:22:50 PM
5/24/2017 2:22:51 PM (First block took 1 second)
5/24/2017 2:22:56 PM (Second block took 5 seconds)

SynchronizationContext に関する追加情報

注:これは私にとって少し霧がかかるところです。何か間違っている場合は修正してください。答えを更新します。これがどのように機能するかを基本的に理解することは重要ですが、 を使用しない限り、専門家でなくても問題はConfigureAwait(false)ありませんが、最適化の機会を失う可能性が高いと思います。

これには、async/のawait概念を理解するのがいくぶんトリッキーになる側面が 1 つあります。これは、この例では、これがすべて同じスレッド (または、少なくともその に関して同じスレッドのように見えるもの) で発生しているという事実ですSynchronizationContext。デフォルトでawaitは、実行されていた元のスレッドの同期コンテキストを復元します。たとえば、ASP.NET ではHttpContext、リクエストが着信したときにスレッドに結び付けられる があります。このコンテキストには、言語、IP アドレス、ヘッダーなどを持つ元の Request オブジェクトなど、元の Http リクエストに固有のものが含まれます。何かを処理している途中でスレッドを切り替えると、別のスレッドでこのオブジェクトから情報を引き出そうとする可能性があります。HttpContextこれは悲惨なことになる可能性があります。コンテキストを何にも使用しないことがわかっている場合は、それを「気にしない」ことを選択できます。これにより、基本的に、コンテキストを持ち歩かずにコードを別のスレッドで実行できます。

どうやってこれを達成しますか?デフォルトでは、await a;コードは実際には、コンテキストをキャプチャして復元することを前提としています。

await a; //Same as the line below
await a.ConfigureAwait(true);

元のコンテキストなしでメイン コードを新しいスレッドで続行できるようにする場合は、単に true の代わりに false を使用して、コンテキストを復元する必要がないことを認識します。

await a.ConfigureAwait(false);

プログラムの一時停止が完了すると、別のコンテキストを持つまったく別のスレッドで続行される可能性があります。これがパフォーマンスの向上の元になるところです。元のコンテキストを復元する必要なく、使用可能なスレッドで続行できます。

これは紛らわしいですか?ええ!あなたはそれを理解できますか?おそらく!概念を理解したら、Stephen Cleary の説明に進みます。この説明は、 async/の技術的な理解をawaitすでに持っている人向けの傾向があります。

于 2017-05-26T14:55:26.933 に答える
156

他の回答に加えて、await (C# リファレンス)をご覧ください。

より具体的には、含まれている例で、状況を少し説明しています

次の Windows フォームの例は、非同期メソッド WaitAsynchronouslyAsync での await の使用を示しています。そのメソッドの動作と WaitSynchronously の動作を比較してください。タスクに await 演算子が適用されていない場合、定義で async 修飾子を使用し、本体で Thread.Sleep を呼び出しているにもかかわらず、WaitSynchronously は同期的に実行されます。

private async void button1_Click(object sender, EventArgs e)
{
    // Call the method that runs asynchronously.
    string result = await WaitAsynchronouslyAsync();

    // Call the method that runs synchronously.
    //string result = await WaitSynchronously ();

    // Display the result.
    textBox1.Text += result;
}

// The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window 
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
{
    await Task.Delay(10000);
    return "Finished";
}

// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
{
    // Add a using directive for System.Threading.
    Thread.Sleep(10000);
    return "Finished";
}
于 2013-01-22T09:39:00.187 に答える
75

最速の学習のために..

  • メソッドの実行フローを理解する (図付き): 3 分

  • 質問内省 (酒を学ぶ): 1 分

  • シンタックス シュガーをすばやく理解する: 5 分

  • 開発者の混乱を共有する: 5 分

  • 問題: 通常のコードの実際の実装を非同期コードにすばやく変更する: 2 分

  • 次はどこへ?

メソッドの実行フローを理解する (図付き): 3 分

この画像では、#6 だけに注目してください (それ以上は何もありません)。 ここに画像の説明を入力

#6 ステップで、実行が不足して停止しました。続行するには、getStringTask(一種の関数) からの結果が必要です。したがって、awaitオペレーターを使用して進行を中断し、呼び出し元 (このメソッドの) に制御を戻します (yield)。getStringTask への実際の呼び出しは、#2 の前半で行われました。#2 では、文字列の結果を返すという約束がなされました。しかし、いつ結果を返すのでしょうか? (#1:AccessTheWebAsync) もう一度 2 回目の呼び出しを行う必要がありますか? #2(calling statement) と #6(awaiting statement) のどちらが結果を取得しますか?

AccessTheWebAsync() の外部呼び出し元も待機中です。したがって、呼び出し側は AccessTheWebAsync を待っており、AccessTheWebAsync は現時点で GetStringAsync を待っています。興味深いことに、AccessTheWebAsync は、おそらく待機時間を節約するために、待機する前にいくつかの作業 (#4) を実行しました。外部の呼び出し元 (およびチェーン内のすべての呼び出し元) も同じようにマルチタスクを自由に実行できます。これが、この「非同期」機能の最大の利点です。同期しているように感じます..または正常ですが、そうではありません。

#2と#6は分割されているので、#4(待機中の作業)の利点があります。しかし、分割せずにそれを行うこともできます。したがって、#2は次のようになりますstring urlContents = await client.GetStringAsync("...");。ここでは利点は見られませんが、チェーンのどこかで 1 つの関数が分割され、残りの関数は分割せずにそれを呼び出します。使用するチェーン内の関数/クラスによって異なります。関数から関数へのこの動作の変化は、このトピックで最も紛らわしい部分です。

メソッドはすでに返されていることを忘れないでください (#2)。再度返すことはできません (2 回目はありません)。では、発信者はどのように知るのでしょうか? タスクがすべてです。タスクが返されました。タスクのステータスが待機されました(メソッドではなく、値ではありません)。値はタスクに設定されます。タスクのステータスは完了に設定されます。Caller は Task(#6) を監視するだけです。したがって、6# は、どこで/誰が結果を取得するかに対する答えです。詳細については、後でここを参照してください。

酒を学ぶための質問の内省: 1 分

質問を少し調整しましょう。

いつ、どのように使用するですか? asyncawait Tasks

学習Taskは自動的に他の 2 つをカバーするため (そして質問に答えます)。

全体のアイデアはとてもシンプルです。メソッドは任意のデータ型 (double、int、object など) を返すことができますが、ここではそれを拒否し、強制的に ' Task' オブジェクトを返します! しかし、まだ戻りデータ (void を除く) が必要ですよね? Taskこれは、' ' オブジェクト内の標準プロパティ (例: ' Result' プロパティ) で設定されます。

シンタックス シュガーをすばやく理解する: 5 分

  • オリジナルの非非同期メソッド
internal static int Method(int arg0, int arg1)
        {
            int result = arg0 + arg1;
            IO(); // Do some long running IO.
            return result;
        }
  • 上記のメソッドを呼び出す新しいタスク化メソッド
internal static Task<int> MethodTask(int arg0, int arg1)
    {
        Task<int> task = new Task<int>(() => Method(arg0, arg1));
        task.Start(); // Hot task (started task) should always be returned.
        return task;
    }

await または async について言及しましたか? いいえ。上記のメソッドを呼び出すと、監視できるタスクが取得されます。タスクが何を返すかはすでにわかっています..整数です。

  • Task の呼び出しは少しトリッキーで、キーワードが表示され始めるのはそのときです。元のメソッドを呼び出すメソッド (非非同期) があった場合は、以下のように編集する必要があります。MethodTask() を呼び出しましょう
internal static async Task<int> MethodAsync(int arg0, int arg1)
    {
        int result = await HelperMethods.MethodTask(arg0, arg1);
        return result;
    }

上記と同じコードを下の画像として追加します。 ここに画像の説明を入力

  1. タスクが完了するのを「待っています」。したがって、await(必須の構文)
  2. await を使用するため、使用する必要がありますasync(必須の構文)
  3. 接頭辞としてMethodAsync をAsync使用 (コーディング標準)

awaitはわかりやすいですが、残りの 2 つ ( asyncAsync) はそうではないかもしれません:)。まあ、それはコンパイラにとってもっと理にかなっているはずです.Further read for later here

したがって、2 つの部分があります。

  1. 「タスク」を作成します(タスクは1つだけで、追加のメソッドになります)

  2. タスクを呼び出すためのシンタックス シュガーを作成しますawait+async(非非同期メソッドを変換する場合は、既存のコードを変更する必要があります)。

AccessTheWebAsync() への外部呼び出し元があったことを思い出してください。その呼び出し元も例外ではありません... つまり、同じものawait+asyncも必要です。そしてチェーンは続きます (したがって、これは多くのクラスに影響を与える可能性のある重大な変更です)。また、元のメソッドがまだ呼び出されるため、破壊的でない変更と見なすこともできます。重大な変更を加えたい場合は、アクセス権を変更 (またはタスク内で削除して移動) すると、クラスは強制的にタスク メソッドを使用するようになります。とにかく、非同期呼び出しでは、常にTask一方の端に があり、1 つしかありません。

大丈夫ですが、ある開発者はTask 行方不明を見て驚いていました...

開発者の混乱を共有する: 5 分

開発者が実装しないというミスを犯しましたTaskが、それでも機能します! 質問と、ここで提供されている受け入れられた回答だけを理解するようにしてください。あなたが読んで完全に理解したことを願っています。要約すると、「タスク」は表示/実装されていない可能性がありますが、親/関連クラスのどこかに実装されています。同様に、私たちの例では、すでに構築された を呼び出す方が、 ( ) ourselfMethodAsync()を使用してそのメソッドを実装するよりもはるかに簡単です。ほとんどの開発者は、コードを非同期コードに変換する際に頭を悩ませるのが難しいと感じています。TaskMethodTask()Tasks

ヒント: 既存の Async 実装 (MethodAsyncや などToListAsync) を探して、問題を外部委託してください。したがって、Async と await を処理するだけで済みます (これは簡単で、通常のコードとよく似ています)。

問題: 通常のコードの実際の実装を非同期操作にすばやく変更する: 2 分

以下のデータ層のコード行が壊れ始めました (多くの場所)。コードの一部を .Net Framework 4.2.* から .Net コアに更新したためです。アプリケーション全体でこれを 1 時間で修正する必要がありました。

var myContract = query.Where(c => c.ContractID == _contractID).First();

簡単!

  1. QueryableExtensions があるため、EntityFramework nuget パッケージをインストールしました。つまり、Async の実装 (タスク) を行うため、シンプルなコードで生き残ることができAsyncますawait
  2. 名前空間 = Microsoft.EntityFrameworkCore

呼び出しコード行はこのように変更されました

var myContract = await query.Where(c => c.ContractID == _contractID).FirstAsync();
  1. メソッド シグネチャが から変更されました

Contract GetContract(int contractnumber)

async Task<Contract> GetContractAsync(int contractnumber)

  1. 呼び出しメソッドも影響を受けました:GetContract(123456);として呼び出されましたGetContractAsync(123456).Result;

待って!それは何Resultですか?よく釣れます!必要な値ではない ( )GetContractAsyncのみを返します。操作の結果が利用可能になると、それは保存され、その後のプロパティへの呼び出しですぐに返されます。同様の「Wait()」でタイムアウトの実装を行うこともできますTaskContractResult

TimeSpan ts = TimeSpan.FromMilliseconds(150);

if (! t.Wait(ts​​)) Console.WriteLine("タイムアウト間隔が経過しました。");

  1. 30分でどこでも変えました!

しかし、アーキテクトは、これだけのために EntityFramework ライブラリを使用しないように私たちに言いました! おっとっと!ドラマ!次に、カスタム Task 実装を作成しました (yuk!)。あなたがどのように知っているか。それでも簡単!..まだユク..

次はどこへ?Converting Synchronous Calls to Asynchronous in ASP.Net Core について見ることができるすばらしい簡単なビデオがあります。おそらく、これを読んだ後に進む方向です。それとも十分に説明しましたか?;)

于 2018-09-08T06:29:55.820 に答える
74

上記の説明を単純なコンソール プログラムで実際に表示すると、次のようになります。

class Program
{
    static void Main(string[] args)
    {
        TestAsyncAwaitMethods();
        Console.WriteLine("Press any key to exit...");
        Console.ReadLine();
    }

    public async static void TestAsyncAwaitMethods()
    {
        await LongRunningMethod();
    }

    public static async Task<int> LongRunningMethod()
    {
        Console.WriteLine("Starting Long Running method...");
        await Task.Delay(5000);
        Console.WriteLine("End Long Running method...");
        return 1;
    }
}

出力は次のとおりです。

Starting Long Running method...
Press any key to exit...
End Long Running method...

したがって、

  1. Main は、 を介して長期実行メソッドを開始しTestAsyncAwaitMethodsます。現在のスレッドを停止せずにすぐに戻り、「終了するには任意のキーを押してください」というメッセージがすぐに表示されます
  2. この間LongRunningMethodずっと、 はバックグラウンドで実行されています。完了すると、スレッドプールからの別のスレッドがこのコンテキストを取得し、最終メッセージを表示します

したがって、スレッドはブロックされません。

于 2015-08-13T09:32:13.183 に答える
51

あなたは悪い例を選んだと思いますSystem.Threading.Thread.Sleep

タスクのポイントはasync、メイン スレッドをロックせずにバックグラウンドで実行できるようにすることです。DownloadFileAsync

System.Threading.Thread.Sleep「行われている」ものではなく、スリープしているだけなので、5秒後に次の行に到達します...

asyncこの記事を読んでください。概念と概念の優れた説明だと思いますawait: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx

于 2013-01-22T09:32:54.840 に答える
25

以下は、フォローしている人々に明確にするための簡単なコンソールプログラムです。TaskToDoメソッドは、非同期にしたい長時間実行されるメソッドです。非同期で実行するには、TestAsyncメソッドによって行われます。テスト ループ メソッドは、TaskToDoタスクを実行して非同期で実行するだけです。実行ごとに同じ順序で完了しないため、結果でそれを確認できます。完了時にコンソール UI スレッドに報告しています。単純ですが、複雑な例よりも単純な例の方がパターンの核心をよく表していると思います。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TestingAsync
{
    class Program
    {
        static void Main(string[] args)
        {
            TestLoops();
            Console.Read();
        }

        private static async void TestLoops()
        {
            for (int i = 0; i < 100; i++)
            {
                await TestAsync(i);
            }
        }

        private static Task TestAsync(int i)
        {
            return Task.Run(() => TaskToDo(i));
        }

        private async static void TaskToDo(int i)
        {
            await Task.Delay(10);
            Console.WriteLine(i);
        }
    }
}
于 2015-07-17T15:36:15.120 に答える
15

この回答は、ASP.NET に固有の情報を提供することを目的としています。

以下の記事で説明されているように、MVC コントローラーで async/await を利用することで、スレッド プールの使用率を高め、スループットを大幅に向上させることができます。

http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4

起動時に多数の同時要求が発生する Web アプリケーションや、負荷が急激に増加する (同時実行が急激に増加する) Web アプリケーションでは、これらの Web サービス呼び出しを非同期にすると、アプリケーションの応答性が向上します。非同期リクエストの処理には、同期リクエストと同じ時間がかかります。たとえば、要求が完了までに 2 秒かかる Web サービス呼び出しを行う場合、その要求は、同期または非同期のどちらで実行されても 2 秒かかります。ただし、非同期呼び出し中、スレッドは、最初の要求が完了するまで待機している間、他の要求への応答をブロックされません。したがって、非同期リクエストは、実行時間の長い操作を呼び出す同時リクエストが多数ある場合に、リクエストのキューイングとスレッド プールの増大を防ぎます。

于 2014-09-08T02:06:42.077 に答える
11

正直なところ、私はまだ最良の説明はウィキペディアでの将来と約束についての説明だと思います:http: //en.wikipedia.org/wiki/Futures_and_promises

基本的な考え方は、タスクを非同期で実行するスレッドの個別のプールがあるということです。使用する場合。ただし、オブジェクトは、ある時点で操作を実行し、要求したときに結果を提供することを約束します。これは、結果を要求して終了していない場合はブロックされますが、それ以外の場合はスレッドプールで実行されることを意味します。

そこから、物事を最適化できます。一部の操作は非同期で実装でき、後続のリクエストをまとめたり、並べ替えたりすることで、ファイルIOやネットワーク通信などを最適化できます。これがすでにMicrosoftのタスクフレームワークに含まれているかどうかはわかりませんが、含まれていない場合は、最初に追加するものの1つになります。

実際には、C#4.0でyieldsを使用して将来のパターンソートを実装できます。それがどのように正確に機能するかを知りたい場合は、まともな仕事をするこのリンクをお勧めします:http ://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/ 。ただし、自分でいじり始めると、すべてのすばらしいことを実行したい場合は、言語サポートが本当に必要であることに気付くでしょう。これは、まさにMicrosoftが行ったことです。

于 2013-01-22T10:16:25.133 に答える
5

私がそれを理解している方法も、ミックスに追加された 3 番目の用語があるはずです: Task.

Async非同期メソッドであることを示すためにメソッドに付ける単なる修飾子です。

Task関数の戻り値ですasync。非同期で実行されます。

あなたawaitはタスクです。コードの実行がこの行に到達すると、制御は周囲の元の関数の呼び出し元に戻ります。

代わりに、async関数の戻り値 (つまりTask) を変数に割り当てると、コードの実行がこの行に到達したときに、が非同期に実行されている、コードの実行は周囲の関数でその行を過ぎて続行されます。Task

于 2017-06-02T21:15:25.070 に答える
5

より高いレベルで:

1) async キーワードは await を有効にし、それだけです。Async キーワードは、別のスレッドでメソッドを実行しません。最初の f async メソッドは、時間のかかるタスクで await にヒットするまで同期的に実行されます。

2) タイプ T の Task または Task を返すメソッドで待機できます。async void メソッドで待機することはできません。

3) メイン スレッドが時間のかかるタスクで await に遭遇した瞬間、または実際の作業が開始されると、メイン スレッドは現在のメソッドの呼び出し元に戻ります。

4) メイン スレッドがまだ実行中のタスクで await を検出した場合、メイン スレッドはそれを待機せず、現在のメソッドの呼び出し元に戻ります。このようにして、アプリケーションは応答性を維持します。

5) 処理タスクの待機は、スレッド プールとは別のスレッドで実行されるようになりました。

6) この待機タスクが完了すると、その下のすべてのコードが別のスレッドによって実行されます

以下はサンプルコードです。実行してスレッドIDを確認

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

namespace AsyncAwaitDemo
{
    class Program
    {
        public static async void AsynchronousOperation()
        {
            Console.WriteLine("Inside AsynchronousOperation Before AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
            //Task<int> _task = AsyncMethod();
            int count = await AsyncMethod();

            Console.WriteLine("Inside AsynchronousOperation After AsyncMethod Before Await, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            //int count = await _task;

            Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await Before DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            DependentMethod(count);

            Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await After DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
        }

        public static async Task<int> AsyncMethod()
        {
            Console.WriteLine("Inside AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
            int count = 0;

            await Task.Run(() =>
            {
                Console.WriteLine("Executing a long running task which takes 10 seconds to complete, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(20000);
                count = 10;
            });

            Console.WriteLine("Completed AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            return count;
        }       

        public static void DependentMethod(int count)
        {
            Console.WriteLine("Inside DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId + ". Total count is " + count);
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Started Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            AsynchronousOperation();

            Console.WriteLine("Completed Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            Console.ReadKey();
        }

    }
}
于 2018-08-05T17:21:39.103 に答える
-1

async は、関数を非同期関数にするために関数と共に使用されます。await キーワードは、非同期関数を同期的に呼び出すために使用されます。await キーワードは、promise が解決されるまで JS エンジンの実行を保持します。

すぐに結果が必要な場合にのみ、 async & await を使用する必要があります。関数から返された結果が次の行で使用されている可能性があります。

このブログをフォローしてください。簡単な言葉で非常によく書かれています

于 2021-02-11T13:39:05.690 に答える