将异步lambda传递给静态方法。无法将lambda表达式转换为类型Task

时间:2014-07-02 22:42:06

标签: c# asynchronous lambda delegates task

所以我试图找出与this回答相对应的正确的异步重载。

为了给出一些上下文,我需要对各个地方进行异步http调用,以检查搜索是否完成,然后再下载文件。该系统通常会返回各种Http错误。

正如已经多次写过的那样,当HttpClient在异步方法中抛出一个错误时,它会抛出一个TaskCanceledException,取消任务,并打破任何后续等待(比如我等待后来的Task.WhenAll)。

所以,这就是我到目前为止所拥有的。我被困在这个阶段。编译器告诉我"无法将lambda表达式转换为' System.Threading.Task.Task'因为它不是代表类型"

我已经查看了大量的SO问题,并在MSDN上阅读了一些关于代理和async / await以及任务,任务< T>,Func< T>,Action等等的文章,并且可以'找出我应该怎么写这一行:

var DownloadResponse = Retry.Do<HttpResponseMessage,TaskCanceledException>
(async ()=> await Client.GetAsync(URL,
           HttpCompletionOption.ResponseHeadersRead),TimeSpan.FromSeconds(2),3);

这里是我编写/修改的异步重载,被称为

 static async Task<T> Do<T, U>(
            Task<T> action,
            TimeSpan retryInterval,
            int retryCount = 3) 
              where T : Task 
              where U : Exception
{
  var exceptions = new List<U>();

  for(int retry = 0; retry < retryCount; retry++)
  {
     try
     {
        return await action;
     }
     catch(Exception ex)
     {
        if(ex is U)
           exceptions.Add(ex as U);
     }
     await Task.Delay(retryInterval);
  }
  throw new AggregateException(exceptions);
}

1 个答案:

答案 0 :(得分:4)

看起来action应该是Func<Task<T>>。请注意,您还可以删除异常的类型检查。

static async Task<T> Do<T, U>(
            Func<Task<T>> action,
            TimeSpan retryInterval,
            int retryCount = 3) 
              where U : Exception
{
  var exceptions = new List<U>();

  for(int retry = 0; retry < retryCount; retry++)
  {
     try
     {
        return await action();
     }
     catch(U ex)
     {
        exceptions.Add(ex);
     }
     catch(Exception ex) { }
     await Task.Delay(retryInterval);
  }
  throw new AggregateException(exceptions);
}