如何将此同步方法转换为返回任务的方法

本文关键字:返回 任务 方法 转换 同步方法 | 更新日期: 2023-09-27 18:11:46

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

由于我在 .Net 4.0 上,我无法使用 async/await(我相信这很容易解决我的问题(,但我想将该方法转换为返回包含以下两个结果之一的任务的方法:

  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;
    }
}

如何将此同步方法转换为返回任务的方法

我建议使用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调用中(这也不是很好,因为你然后通过异步进行异步同步,这是非常低效的(。 这会产生大量代码,并使整体流程更难遵循。