async await returnタスク


131

誰かがこれが同期メソッドに何を意味するのか説明できますか?メソッドをに変更しようとするとasync、VSはそれについて文句を言います。

これは機能します:

public Task MethodName()
{
     return Task.FromResult<object>(null);
}

これは機能しません:

public async Task MethodName()
{
     return Task.FromResult<object>(null);
}

だから基本的に私はこれが正確に何を意味するのか知りたいです: Task.FromResult<object>(null);



@LBうーん動作します!しかし、私もうまくいくならreturn;...!
David Dury

2
「機能しない」は、機能していないものについての非常に良い説明を提供しません。表示されるエラーメッセージは何ですか?
John Koerner、2014

@JohnKoerner void関数で値を返そうとした場合と同じエラーがコンパイラーから出力される可能性があることは明らかです。
binki 2015年

回答:


236

asyncメソッドは通常のメソッドとは異なります。asyncメソッドから返されるものはすべてにラップされますTask

値を返さない場合(void)はにラップされTaskます。返すint場合はラップさTask<int>れます。

非同期メソッドが返す必要がある場合intは、メソッドの戻り値の型をとしてマークし、ではなくTask<int>プレーンを返します。コンパイラが変換されますへのあなたのため。intTask<int>intTask<int>

private async Task<int> MethodName()
{
    await SomethingAsync();
    return 42;//Note we return int not Task<int> and that compiles
}

Sameway、Task<object>メソッドの戻り値の型はTask<Task<object>>

public async Task<Task<object>> MethodName()
{
     return Task.FromResult<object>(null);//This will compile
}

メソッドがを返しているので、Task値は返されません。それ以外の場合はコンパイルされません。

public async Task MethodName()
{
     return;//This should work but return is redundant and also method is useless.
}

awaitステートメントのない非同期メソッドはそうではないことに注意してくださいasync


1
私にとって、この戻り値の型は機能しません(私は何か間違っていると思います)。静的asyncの Task <string> DoStuff(){... = await SomeMethodAsync(); 「文字列値」を返します。} .. var x = DoStuff(); しかし、このx-タイプは「Task <string>」であり、タイプ「string」ではありません... なぜそうなのですか?
Prokurors、2015

3
@ProkurorsあなたDoStuff()も待つ必要があります。例:var x = await DoStuff();
Sriram Sakthivel、2015

5
する必要がありますreturn await Task.FromResult<object>(null);
Sandeep talabathula

@sandeeptalabathulaはnullを返す
Sriram Sakthivel

2
@ProfK Task.WhenAnyは一例です。
Servy

55

asyncを使用し、関数の戻り値の型が汎用である場合は、awaitキーワードを使用する必要があります。戻り値の例を次に示します。

public async Task<object> MethodName()
{
    return await Task.FromResult<object>(null);
}

以下は戻り値のない例です:

public async Task MethodName()
{
    await Task.CompletedTask;
}

これらを読んでください:

TPL:http ://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx およびタスク:http : //msdn.microsoft.com/en-us/library/system.threading .tasks(v = vs.110).aspx

非同期:http: //msdn.microsoft.com/en-us/library/hh156513.aspx待機:http : //msdn.microsoft.com/en-us/library/hh156528.aspx


9
nullダミーのタスクを待つ代わりに、直接戻ることができます。
リー

5
@Lee、しかしそれを行うと、コンパイラはasyncメソッドが非同期で実行さawaitれ、メソッド内のどこかでキーワードを使用するように提案することを警告します。コンパイラの警告ノイズを減らすために、キーワードを使用return Task.FromResult((object)null);して削除することをお勧めしasyncます。
binki 2015年

はい、私はreturnタスクで使用しただけですが、タスクが実行され続けます。なぜなら、return返されないからですTask
ターナーベース

30

asyncキーワードの追加は、ステートマシンの作成を簡略化するための単なる構文上の砂糖です。本質的に、コンパイラーはコードを受け取ります。

public async Task MethodName()
{
     return null;
}

そしてそれを変える;

public Task MethodName()
{
     return Task.FromResult<object>(null);
}

コードにawaitキーワードがある場合、コンパイラはメソッドを取得してクラスに変換し、実行に必要なステートマシンを表す必要があります。各awaitキーワードでは、変数とスタックの状態がクラスのフィールドに保存され、クラスは待機中のタスクに完了フックとしてそれ自体を追加してから戻ります。

そのタスクが完了すると、タスクが再度実行されます。したがって、変数の状態を復元し、コードの次のスラブにジャンプするために、いくつかの追加のコードがメソッドの上部に追加されます。

async&awaitは何を生成するかを参照してください悲惨な例のために。

このプロセスは、コンパイラーがyieldステートメントを使用してイテレーターメソッドを処理する方法と多くの共通点があります。


2

これは、文字列型のタスクを返すタスクです(C#の無名関数または言い換えると、委任は「Func」が使用されます)。

    public static async Task<string> MyTask()
    {
        //C# anonymous AsyncTask
        return await Task.FromResult<string>(((Func<string>)(() =>
        {
            // your code here
            return  "string result here";

        }))());
    }

1
回答としてコードを投稿するときは、何を示しているかについての説明を含めてください。この場合、すでにいくつかの回答がある古い質問に回答を追加しています。他の回答ではまだ表示されていなかった、新しい回答が示していることを説明する1つまたは2つの文を追加してください。私はあなたの答えで何か間違っていると言っているのではなく、あなたがあなたのコードで示しているものを言葉にして他の人を助けるように頼むだけです。
ToolmakerSteve

0

非同期メソッドから適切な応答を返すには、それらのタスクメソッドを呼び出すまで待機する必要があります。これは、タスクタイプではなく戻り値のタイプに変換されるのを待ちます。

たとえば、var content = await StringAsyncTask(

where public async Task < String > StringAsyncTask())

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.