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

时间:2013-05-02 16:41:35

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

我有一个方法或多或少地调用三个不同的Async方法,然后返回一个包含成功消息的“Result”对象。这三种异步方法中的任何一种都可能会抛出SshException,因此我将所有三种方法都置于try{}catch{}内,陷阱AggregateException,处理SshException,然后返回失败结果对象。

因为我在.Net 4.0上,我不能使用async / await(我相信它可以很容易地解决我的问题),但是我想把这个方法变成一个返回包含两个结果之一的Task的方法:

  1. 如果前三个任务都成功完成,则“成功”。
  2. “失败”,如果先前任务的任何出现故障。理想情况下,任务执行也会在第一个被取消的任务中停止(例如,对于三个工作任务,TaskContinuationOptions.NotOnFaulted)。
  3. 以下是一些示例代码:

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

1 个答案:

答案 0 :(得分: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调用中(这不是'真的很好,因为你正在通过异步进行同步异步,这是非常低效的)。这会产生大量代码,并使整个流程更难以遵循。