为什么这个异步lambda函数调用不能在C#中编译?

时间:2016-11-12 00:22:03

标签: c# asynchronous lambda async-await

在我的理解中,我似乎遗漏了一些非常基本的东西。我试图调用异步函数,如果异步函数没有在缓存中找到值,则调用者将传入Func<T>。我真的很困惑为什么我的代码不会编译。

我的主叫代码如下

static void Main(string[] args)
{
    Func<Task<string>> dataFetcher = async () =>
    {
        string myCacheValue = await new HttpClient().GetStringAsync("http://stackoverflow.com/");
        return myCacheValue;
    };

    MyCache<string> cache = new MyCache<string>();

    string mValue = cache.GetOrCreateAsync("myCacheKey", dataFetcher).Result;

}

MyCache如下

internal class MyCache<T> where T: class
{
    private Cache localCache = null;

    public MyCache()
    {
        localCache = new Cache();
    }
    public T GetOrCreate(string cacheKey, Func<T> doWork)
    {
        T cachedObject = null;
        if (string.IsNullOrEmpty(cacheKey) || string.IsNullOrWhiteSpace(cacheKey))
            return cachedObject;

        cachedObject = localCache.Get(cacheKey) as T;

        if (null == cachedObject)
        {
            cachedObject = doWork();
        }

        localCache.Add(cacheKey, cachedObject, null, DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);

        return cachedObject;
    }

    public async Task<T> GetOrCreateAsync(string cacheKey, Func<T> doWork)
    {
        T cachedObject = null;

        if (string.IsNullOrEmpty(cacheKey) || string.IsNullOrWhiteSpace(cacheKey))
            return cachedObject;

        try
        {
            cachedObject = await Task.Factory.StartNew<T>(doWork);
            localCache.Add(cacheKey, cachedObject, null, DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
        }
        catch (Exception)
        {
            cachedObject = null;
        }
        finally
        {
        }

        return cachedObject;
    }
}

在调用代码中行

string mValue = cache.GetOrCreateAsync("myCacheKey", dataFetcher).Result;

给了我一个编译时错误Argument 2: cannot convert from System.Func<System.Threading.Tasks.Task<string>> to System.Func<string>

我不知道我错过了什么?如果有人可以提供帮助那就太棒了!

由于 〜KD

1 个答案:

答案 0 :(得分:1)

使用重载方法并向其传递Func<Task<T>>参数。然后你可以等待那个结果(Task<T>)。

public async Task<T> GetOrCreateAsync(string cacheKey, Func<Task<T>> doWorkAsync)
{
    T cachedObject = null;

    if (string.IsNullOrEmpty(cacheKey) || string.IsNullOrWhiteSpace(cacheKey))
        return cachedObject;

    try
    {
        cachedObject = await doWorkAsync();
        localCache.Add(cacheKey, cachedObject, null, DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
    }
    catch (Exception)
    {
        cachedObject = null;
    }
    finally
    {
    }

    return cachedObject;
}