2016-03-23 26 views
1

私は使用可能な言語をフェッチするAPIエンドポイントを構築しました。私のMVCアプリケーションでは、言語を非同期にフェッチするヘルパーがいます。私は、ユーザーが選択できる利用可能な言語のリストにドロップダウンリストをバインドしたい私のViewgetter内部で非同期メソッドを呼び出すと例外がスローされます

public static async Task<Languages> GetLanguagesAsync() 
{ 
    var apiResponse = await APIHelper.GetContentGetAsync("Languages").ConfigureAwait(false); 
    return apiResponse.LanguagesDataModel; 
} 

:メソッドは次のように定義されています。

Html.DropDownListFor @

(M => m.Language、LanguageHelper.AvailableLanguages)

getterは、以下の定義されます。

public static IEnumerable<SelectListItem<string>> AvailableLanguages 
{ 
    get 
    { 
     var result = GetLanguagesAsync().Result; 
     return new List<SelectListItem<string>>(result.Languages.Select(l => new SelectListItem<string> {Value = l.Key, Text = l.Value})); 
    } 
} 

しかし、私はいつものエラーが出ますhereからの最も上に上げられた答えである行var result = GetLanguagesAsync().Result;

スローされた例外は、非同期操作は、この時点で開始することはできません

です。非同期操作は、非同期ハンドラまたはモジュール内、またはページライフサイクルの特定のイベント中にのみ開始できます。ページの実行中にこの例外が発生した場合は、Pageが<%@ Page Async = "true"%>とマークされていることを確認してください。この例外は、ASP.NET要求処理では一般的にサポートされていない「非同期void」メソッドの呼び出しを示す可能性があります。代わりに、非同期メソッドはTaskを返す必要があり、呼び出し元はそれを待つ必要があります。

hereと同様に、呼び出されたアクションはasyncとマークされます。

+4

メッセージが十分にクリアではありませんか?あなたのページで '<%@ Page Async =" true "%>'指示文を使う必要があります。最新のバージョンではこれが必要ないため、古いASP.NET MVCバージョンを使用していると思われます。これは 'async/await'キーワードとは関係ありません。 –

+1

'.Result'を使わず、' await GetLanguagesAsync() 'を使用してください。 – Mafii

+1

@Mafli非同期のプロパティはありません –

答えて

1

今日、同期ブロッキング(is a design mistake)でこれらの呼び出しをラッピングしている場合でも、Razorコードは非同期呼び出しを処理できません。アクションが完了した後は、ビューの処理中であるため、アクションがasyncであることは重要ではありません。

ASP.NETコアに非同期ビューが追加されました。しかし、それはまだ珍しいユースケースであるべきです。一般的に

、あなたのオプションは次のとおりです。

  • は、「すべての道」のヘルパーが同期してください。すなわち、非同期の代わりに同期API呼び出しを使用して、同期オーバーアシンクコードを取り除く。
  • (おそらく、共通のVMベースの一部として)ビューモデルにデータを追加します。

この特定のケースでは、私はPanagiotisのコメントに同意します。この種の不変の情報は、1回の呼び出しで1回ではなく、アプリごとに1回読み込むようにしてください。 Lazy<T>の中に同期実装をラップするのが最も簡単な解決策です。

+0

ありがとうございます。すでに言及したように、必要に応じて一度データを同期的に取得し、その結果を 'Lazy >'に保存するようにコードを変更しました。 – KingKerosin

関連する問題