【问题标题】:Is Image guaranteed to be disposed in this method?Image 是否保证以这种方法处理?
【发布时间】:2020-01-17 16:29:20
【问题描述】:

鉴于resizedImageSystem.Drawing.Image 类型的代码:

using (var resizedImage = Resizer.ResizeImage(bytes, requestedWidth))
{
    return PNGCompressor.LosslesslyCompressPNG(resizedImage);
}

并且方法定义为:

public static byte[] LosslesslyCompressPNG(Image image)
{
    var fileName = Guid.NewGuid();
    var inputFilePath = TempCompressionFolder + fileName + ".png";
    image.Save(inputFilePath, ImageFormat.Png);

    var outputFilePath = TempCompressionFolder + fileName + "_comp.png";

    var startInfo = new ProcessStartInfo
    {
        FileName = PathToOptiPNGExe,
        WindowStyle = ProcessWindowStyle.Hidden,
        CreateNoWindow = true,
        Arguments = "\"" + inputFilePath + "\" -out \"" + outputFilePath + "\" -o2 -strip all"
    };
    using (var process = Process.Start(startInfo))
    {
        if (process == null)
        {
            throw new Exception("Could not start " + PathToOptiPNGExe);
        }
        process.WaitForExit(Settings.Executables.WaitForExitMS);
        if (!process.HasExited)
        {
            process.Kill();
        }
    }

    var bytes = File.ReadAllBytes(outputFilePath);
    File.Delete(outputFilePath);
    File.Delete(inputFilePath);
    return bytes;
}

resizedImage 会一直被处理掉吗?我想知道这是否是由于新进程正在启动而导致内存泄漏的原因。

【问题讨论】:

    标签: c# asp.net memory-leaks idisposable


    【解决方案1】:

    using statement 保证Dispose 即使在出现异常的情况下也会被调用。

    您正在启动新进程这一事实不会对这个实例做任何事情,因为您没有将实例与这个新进程一起使用,只有string 参数。即使您正在使用此实例(通过流参数或其他方式),using 语句也会处理和释放该实例。

    顺便说一句,我的理解是您使用 optipng 工具只是为了“剥离”元数据。还有许多其他方法可以做到这一点,而无需在磁盘上创建文件并启动新进程。以easy way to clean metadata from an image 为例

    【讨论】:

    • 非常感谢您的确认。该过程会去除元数据,但也会对其进行无损压缩。我认为这不再是必要的,因为 Cloudflare 层会处理此问题,因此可能会根据您的建议将其关闭。
    猜你喜欢
    • 2016-10-30
    • 1970-01-01
    • 2012-05-04
    • 2021-03-01
    • 2019-01-09
    • 2021-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多