C#转换同步方法异步方法 [英] C# convert sync method to async method

查看:143
本文介绍了C#转换同步方法异步方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们得到了一个现有的库,其中的一些方法需要被转换为异步方法。

不过我不知道如何与下面的方法做(ErrorHandling中已被删除)。该方法的目的是压缩文件并将其保存到磁盘。 (请注意,压缩类不公开任何异步方法。)

 公共静态布尔ZipAndSaveFile(字符串fileToPack,串archiveName,串输出目录)
{
    VAR archiveNameAndPath = Path.Combine(输出目录,archiveName);
    使用(VAR邮编=新的ZipFile())
    {
        zip.Com pressionLevel = Ionic.Zlib.Com pressionLevel.BestCom pression;
        zip.Comment = ${(G)(UTC)这个档案在System.DateTime.UtcNow.ToString}创造;
        zip.AddFile(fileToPack);
        zip.Save(archiveNameAndPath);
    }
    返回true;
}

这是实现可能是这样的:

 公共静态异步任务<布尔> ZipAndSaveFileAsync(字符串fileToPack,串archiveName,串输出目录)
{
    VAR archiveNameAndPath = Path.Combine(输出目录,archiveName);
    等待Task.Run(()=>
    {
        使用(VAR邮编=新的ZipFile())
        {
            zip.Com pressionLevel = Ionic.Zlib.Com pressionLevel.BestCom pression;
            zip.Comment = ${(G)(UTC)这个档案在System.DateTime.UtcNow.ToString}创造;
            zip.AddFile(fileToPack);
            zip.Save(archiveNameAndPath);
        }
    });
    返回true;
}

这似乎只是错误的。客户端可以只用打电话的Task.Run同步方法

请,任何人有关于如何将其改造成一个异步方法任何提示?


解决方案

  

这似乎只是错误的。该客户端可以只调用同步方法
  使用Task.Run


现货上。通过在Task.Run包装同步code()的库现在是使用客户端的线程池资源,而它是显而易见的。想象一下会发生什么,到客户端的线程池,如果所有的库采取这种方式?长话短说,只是露出同步方法,让客户决定是否要包装在Task.Run()。

说了这么多,如果zip文件对象有异步功​​能(例如有一个SaveAsync()方法),那么你可以让外部异步方法为好。这里有一个如何,将看一个例子:

 公共静态异步任务<布尔> ZipAndSaveFileAsync(字符串fileToPack,串archiveName,串输出目录)
{
    VAR archiveNameAndPath = Path.Combine(输出目录,archiveName);
    使用(VAR邮编=新的ZipFile())
    {
        // 做东西
        等待zip.SaveAsync(archiveNameAndPath);
    }
    返回true;
}

We got an existing library where some of the methods needs to be converted to async methods.

However I'm not sure how to do it with the following method (errorhandling has been removed). The purpose of the method is to zip a file and save it to disk. (Note that the zip class doesn't expose any async methods.)

public static bool ZipAndSaveFile(string fileToPack, string archiveName, string outputDirectory)
{
    var archiveNameAndPath = Path.Combine(outputDirectory, archiveName);
    using (var zip = new ZipFile())
    {
        zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;
        zip.Comment = $"This archive was created at {System.DateTime.UtcNow.ToString("G")} (UTC)";
        zip.AddFile(fileToPack);
        zip.Save(archiveNameAndPath);
    }
    return true;
}

An implementation could look like this:

public static async Task<bool> ZipAndSaveFileAsync(string fileToPack, string archiveName, string outputDirectory)
{
    var archiveNameAndPath = Path.Combine(outputDirectory, archiveName);
    await Task.Run(() => 
    {
        using (var zip = new ZipFile())
        {
            zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;
            zip.Comment = $"This archive was created at {System.DateTime.UtcNow.ToString("G")} (UTC)";
            zip.AddFile(fileToPack);
            zip.Save(archiveNameAndPath);
        }
    });
    return true;
}

Which just seems wrong. The client could just call the sync method using Task.Run

Please, anyone got any hints on how to transform it into a async method ?

解决方案

Which just seems wrong. The client could just call the sync method using Task.Run

Spot on. By wrapping synchronous code in Task.Run() the library is now using the client's threadpool resources without it being readily apparent. Imagine what could happen to the client's threadpool if all libraries took this approach? Long story short, just expose the synchronous method and let the client decide if it wants to wrap it in Task.Run().

Having said that, if the ZipFile object had async functionality (e.g. had a SaveAsync() method) then you could make the outer method async as well. Here's an example of how that would look:

public static async Task<bool> ZipAndSaveFileAsync(string fileToPack, string archiveName, string outputDirectory)
{
    var archiveNameAndPath = Path.Combine(outputDirectory, archiveName);
    using (var zip = new ZipFile())
    {
        // do stuff
        await zip.SaveAsync(archiveNameAndPath);
    }   
    return true;
}

这篇关于C#转换同步方法异步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆