web-dev-qa-db-ja.com

async / awaitメソッドからリストを返す

非同期のWebサービス要求を作成したい。私はここでそれを呼び出します:

_List<Item> list = GetListAsync();
_

リストを返す関数の宣言は次のとおりです。

_private async Task<List<Item>> GetListAsync(){
    List<Item> list = await Task.Run(() => manager.GetList());
    return list;
}
_

コンパイルしたい場合、次のエラーが表示されます

_Cannot implicitely convert type System.Threading.Tasks.Task<System.Collections.Generic.List<Item>> to System.Collections.Generic.List<Item>
_

async修飾子を使用すると、結果はTaskで自動的にラップされます。 _Task.Run_を使用しているため、これは起こらないと思います。 Task.Run(() =>部分を削除すると、

System.Collections.Generic.List式を待つことはできません

私はasync/awaitメソッドを完全に理解していないと思います。私が間違っているのは何ですか?

20
testing

リストがダウンロードされるのを待つようにコードを修正する必要があります。

_List<Item> list = await GetListAsync();
_

また、このコードが配置されているメソッドにasync修飾子があることを確認してください。

このエラーが発生する理由は、GetListAsyncメソッドが完了した結果ではない_Task<T>_を返すためです。リストは(Task.Run()により)非同期にダウンロードされるため、awaitキーワードを使用してタスクから値を「抽出」する必要があります。

Task.Run()を削除すると、リストは同期的にダウンロードされ、Taskasync、またはawaitを使用する必要はありません。

もう1つの提案:操作を別のスレッドに委任するだけであれば、GetListAsyncメソッドで待つ必要はありません。そのため、コードを次のように短縮できます。

_private Task<List<Item>> GetListAsync(){
    return Task.Run(() => manager.GetList());
}
_
46
takemyoxygen

@takemyoxygenの答えに加えて、Asyncで終わる関数名を持つという規則は、この関数が本当に非同期であることです。つまり新しいスレッドを開始せず、単にTask.Runを呼び出しません。それがあなたの関数にあるすべてのコードである場合、それを完全に削除し、単に持っている方が良いでしょう:

List<Item> list = await Task.Run(() => manager.GetList());
10
Ned Stoyanov

私のために働く:

List<Item> list = Task.Run(() => manager.GetList()).Result;

この方法では、呼び出しでメソッドを非同期でマークする必要はありません。

1
sergiokml