【问题标题】:How do I turn this synchronous method into one that returns a Task?如何将此同步方法转换为返回任务的方法?
【发布时间】:2013-04-26 22:33:40
【问题描述】:

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

由于我在 .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;
    }
}

【问题讨论】:

    标签: c# .net-4.0 task-parallel-library


    【解决方案1】:

    我建议使用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 调用中(这不是真的也很好,因为您随后在异步上进行异步同步,这是非常低效的)。这会创建大量代码,并使整体流程更加难以遵循。

    【讨论】:

    • 关于 Microsoft.Bcl.Async 的好提示,我不知道它是否可用!在发布之前,我尝试了您的第二种选择(让每个任务作为前一个任务的延续),但我无法弄清楚如何从this.GetFilename() 延续中捕获并返回UploadResult 如果 that 任务抛出 SshException。我是不是错过了什么?
    • @nemec 问题是您必须让每个任务检查异常,然后重新抛出到下一个,然后让最后一个继续处理它 - 或者您需要更改返回类型处理它的中间任务。这很难看,这就是为什么我说这是一个更好的方法;)
    猜你喜欢
    • 2021-04-12
    • 1970-01-01
    • 2019-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    相关资源
    最近更新 更多