异步转换前的lambda pression委托类型System.Func< T&GT ;? [英] Convert async lambda expression to delegate type System.Func<T>?

查看:242
本文介绍了异步转换前的lambda pression委托类型System.Func< T&GT ;?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个便携式类库里面异步方法与此签名:

I have an async method inside a portable class library with this signature:

private async Task<T> _Fetch<T>(Uri uri)

它获取被投回为一个具体类型T的资源。

It fetches a resource that is cast back as a concrete type T.

我正在与第三方缓存库工作( Akavache ),需要一个 Func键&LT; T&GT 作为参数之一,曾尝试在这种方式这样做的:

I'm working with a 3rd party cache library (Akavache) that requires a Func<T> as one of the parameters and have tried to do so in this manner:

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

这导致错误:

无法转换异步拉姆达前pression委托类型 System.Func&LT; T&GT; 。一个异步的lambda前pression可以返回无效工作任务&LT; T&GT; ,其中没有一个是转换为 System.Func&LT; T&GT;

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键&LT的各种排列; T&GT; 分配没有任何运气,我可以得到code工作的唯一方法是使 Func键&LT; T&GT; 阻塞:

I've tried various permutations of Func<T> assignment without any luck, the only way I can get the code to work is to make the Func<T> blocking:

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

这会造成死锁我的应用程序。

which deadlocks my app.

这是我误入歧途,其中任何指针?

Any pointers on where I'm going astray?

推荐答案

没有能做到。当有人需要一个 Func键&LT; T&GT; ˚F你可以假设它的东西,如的结果= F调用() - 即,它不知道异步行为。如果通过欺骗它。结果像你这样 - 它会在UI线程死锁,因为它要安排后,code 的await 在UI线程(在_Fetch),但是你已经有阻止它。结果

No can do. When someone expects a Func<T> f you can assume it will be invoked with something like result = f() - i.e., it does not know about async behavior. If you cheat it by using .Result like you have - it will deadlock on UI thread because it wants to schedule the code after await (in _Fetch) on the UI thread, but you have already blocked it with .Result.

异步拉姆达可以传递给动作,因为它没有返回值 - 或 Func键&LT;任务&GT; Func键&LT;任务&LT; T&GT;&GT;

Async lambda can be passed to Action since it has no return value - or to Func<Task> or Func<Task<T>>.

看你的情况下, GetOrCreateObject 似乎调用 GetOrFetchObject 。其中的 GetOrFetchObject 重载接受 Func键&LT;任务&LT; T&GT;&GT; 。您可以尝试调用一个方法,你的异步拉姆达,看看它是否会有所帮助。

Looking at your case, the GetOrCreateObject appears to be calling GetOrFetchObject. One of the GetOrFetchObject overloads accepts a Func<Task<T>>. You can try calling that method with your async lambda and see if it helps.

这篇关于异步转换前的lambda pression委托类型System.Func&LT; T&GT ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆