2013-06-21 14 views
18

私はこのシグネチャを持つポータブルクラスライブラリ内部での非同期メソッドを持っていますこれはエラーになり非同期ラムダ式を代入するSystem.Func <T>?それは私がサードパーティのキャッシュで働いている</p> <p>コンクリート型Tとしてバックキャストされたリソースを取得し</p> <pre><code>private async Task<T> _Fetch<T>(Uri uri) </code></pre> <p>:

await this.CacheProvider.GetOrCreateObject<T>(key, 
    async() => await _Fetch<T>(uri), cacheExpiry); 

:パラメータの一つとしてFunc<T>を必要とし、このようにそうしようとしたライブラリー(Akavache

私のアプリをデッドロック

await this.CacheProvider.GetOrCreateObject<T>(key, 
    () => _Fetch<T>(uri).Result, cacheExpiry); 

Cannot convert async lambda expression to delegate type ' System.Func<T> '. An async lambda expression may return void , Task or Task<T> , none of which are convertible to ' System.Func<T> '.

私は運なしFunc<T>割り当ての様々な順列を試してみた、私は仕事にコードを取得することができます唯一の方法は、Func<T>ブロックを作ることです。

私が迷っている場所のポインタはありますか?

+0

あなたは 'Func ' –

答えて

13

できません。誰かがFunc<T> fを期待すると、result = f()のようなものが呼び出されると仮定できます。つまり、非同期動作についてはわかりません。 UIのスレッドでawait(_Fetchで)の後にコードをスケジュールする必要があるため、既に.Resultでブロックしているため、UIスレッドでデッドロックします。.Result

非同期ラムダは、戻り値がないためActionに渡すことも、Func<Task>またはFunc<Task<T>>に渡すこともできます。

あなたのケースを見ると、GetOrCreateObjectGetOrFetchObjectと表示されているようです。 GetOrFetchObject過負荷の1つは、Func<Task<T>>を受け入れます。非同期ラムダでそのメソッドを呼び出すと、それが役立つかどうかを調べることができます。

+3

を探しています。メソッドが 'Action'を受け入れ、' async'ラムダを渡すと、ほとんどの場合、それは間違っていることを強調したいと思います。 – svick

+0

@スウィック:はい、あなたに同意します。 'Func 'を受け入れるメソッドのように、 'Action'を受け入れるメソッドは、その非同期動作を知らないでしょう。結果を返さない非同期ラムダは理想的には 'Func 'に渡されます。そのC#コンパイラでは、戻り値がないため、 'Action'に渡すことができます。 – YK1

+0

ありがとうございましたYK1、私は今、かなりばかげています。私はキャッシュプロバイダを抽象化するためのインタフェースを実装していました。 –

-3

これは何か?

Public Func<T> ConvertTask<T>(Task<T> task) 
{ 
    return()=>task.Result; 
} 
+0

「Result」を使用するとデッドロックが発生することは明らかです。 – svick

4

YK1's answerあなたは非同期としてFunc<T>を扱うことができない理由を説明します。

GetOrCreateObjectの代わりにGetOrFetchObjectを使用して問題を解決してください。 「作成」メソッドは(同期)作成を前提とし、「フェッチ」メソッドは(非同期)検索で機能します。

await CacheProvider.GetOrFetchObject<T>(key,() => _Fetch<T>(uri), cacheExpiry) 

私はまた、あなたのラムダ式でasync/await不要を削除しました。 _FetchはすでにTask<T>を返すので、asyncラムダを作成する必要はありません。その目的はそのタスクawaitです。

+0

スティーブン、ありがとう、これは私が問題を解決する方法を正確にしています。 –

関連する問題

 関連する問題