60

私はこのような方法を持っています:

public static async Task SaveAllAsync()
{
    foreach (var kvp in configurationFileMap)
    {
        using (XmlWriter xmlWriter = XmlWriter.Create(kvp.Value, XML_WRITER_SETTINGS))
        {
            FieldInfo[] allPublicFields = 
                           kvp.Key.GetFields(BindingFlags.Public | BindingFlags.Static);
            await xmlWriter.WriteStartDocumentAsync();
            foreach (FieldInfo fi in allPublicFields)
            {
                await xmlWriter.WriteStartElementAsync("some", "text", "here");
            }
            await xmlWriter.WriteEndDocumentAsync();
        }
    }
}

しかし、誰かが電話をかけたときに何が起こるかを追うのに苦労していますSaveAllAsync()

私が起こると思うことはこれです:

  1. 誰かが最初にそれを呼び出すと、SaveAllAsync()行の呼び出し元に制御が戻りますawait xmlWriter.WriteStartDocumentAsync();
  2. 次に... 彼らが待っているときSaveAllAsync()(またはタスクを待っているとき)... どうなりますか? SaveAllAsync()それが呼び出されるまで、まだ最初の待機に固執しますか? スレッド化が関係していないので、その通りだと思います...
4

4 に答える 4

60

その操作が完了するまでメソッドawaitを「一時停止」すると考えることができます。async特殊なケースとして、操作がすでに完了している (または非常に高速である) 場合、awaitはメソッドを「一時停止」しません。すぐに実行を継続します。

WriteStartDocumentAsyncしたがって、この場合 (まだ完了していないと仮定して)awaitはメソッドを一時停止し、未完了のタスクを呼び出し元に返します。Taskメソッドによって返される はそのasyncメソッドを表すことに注意してください。メソッドが完了すると、それTaskが完了します。

最終的にWriteStartDocumentAsyncは完了し、残りのasyncメソッドが実行を継続するようにスケジュールされます。この場合、メソッドの次の部分が次の まで実行awaitされ、再び一時停止されるときなどです。最終的にasyncメソッドが完了し、Taskそのメソッドを表すために返された が完了します。

詳細については、ブログにasync/awaitイントロがあります。

于 2013-08-26T13:52:54.557 に答える