1

我有一个方法或多或少调用三个不同的异步方法,然后返回一个包含成功消息的“结果”对象。这三个 Async 方法中的任何一个都可能抛出一个SshException,所以我将所有三个都放在一个try{}catch{}捕获AggregateException、处理SshException、然后返回失败结果对象的 a 中。

由于我使用的是 .Net 4.0,因此我无法使用 async/await(我相信这可以轻松解决我的问题),但我想将该方法转换为返回包含以下两个结果之一的 Task 的方法:

  1. 如果前面三个任务都成功完成,则为“成功”。
  2. 如果之前的任何任务出现故障,则为“失败” 。理想情况下,任务执行也会在第一个取消的任务处停止(例如,三个工作任务的 TaskContinuationOptions.NotOnFaulted)。

这是一些示例代码:

public UploadResult UploadFileToDir(string dir, string text)
{
    try
    {
        SftpClient.Cd(dir).Wait();  // This is a Task
        var filename = this.GetFilename().Result;  // This is also a Task
        SftpClient.WriteFile(filename, text).Result;  // This is the last Task
        return UploadResult.Success;
    }
    catch(AggregateException agg)
    {
        if(agg.InnerException is SshException)
        {
            return UploadResult.Failure;
        }
        throw;
    }
}
4

1 回答 1

4

我建议使用Microsoft.Bcl.Async,它允许您在 .NET 4 项目中使用async/ 。await这将允许你写:

public async Task<UploadResult> UploadFileToDir(string dir, string text)
{
    try
    {
        await SftpClient.Cd(dir)
        var filename = await this.GetFilename();
        await SftpClient.WriteFile(filename, text);
        return UploadResult.Success;
    }
    catch(SshException ex)
    {
        return UploadResult.Failure;
    }
}

没有这个,你必须让每个任务作为前一个任务的延续,并返回最终的任务延续,或者只是把你现有的代码包装在一个Task.Factory.StartNew调用中(这也不是很好,因为你'然后重新在异步上进行异步同步,这是非常低效的)。这会创建大量代码,并使整体流程更加难以遵循。

于 2013-05-02T16:44:13.363 回答