Browse Source

Optimization of Stream and Resource Management

- Replaced TryCopyToMemoryStreamAsync methods with direct response stream returns in AliyunBlobProvider, AwsBlobProvider, AzureBlobProvider, and FileSystemBlobProvider.
- Used using to properly dispose of Image objects in ImageSharpImageCompressorContributor and ImageSharpImageResizerContributor.
- Replaced Dispose calls with DisposeAsync for asynchronous resource management in ImageSharpImageCompressorContributor and ImageSharpImageResizerContributor.
- Simplified image resizing code in SkiaSharpImageResizerContributor with nested using statements.
pull/21631/head
1d0n7kn0w 2 years ago
parent
commit
311fa3f9b4
  1. 2
      framework/src/Volo.Abp.BlobStoring.Aliyun/Volo/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs
  2. 2
      framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/AwsBlobProvider.cs
  3. 3
      framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs
  4. 8
      framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProvider.cs
  5. 17
      framework/src/Volo.Abp.Imaging.ImageSharp/Volo/Abp/Imaging/ImageSharpImageCompressorContributor.cs
  6. 6
      framework/src/Volo.Abp.Imaging.ImageSharp/Volo/Abp/Imaging/ImageSharpImageResizerContributor.cs
  7. 43
      framework/src/Volo.Abp.Imaging.SkiaSharp/Volo/Abp/Imaging/SkiaSharpImageResizerContributor.cs

2
framework/src/Volo.Abp.BlobStoring.Aliyun/Volo/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs

@ -86,7 +86,7 @@ public class AliyunBlobProvider : BlobProviderBase, ITransientDependency
return null; return null;
} }
var result = ossClient.GetObject(containerName, blobName); var result = ossClient.GetObject(containerName, blobName);
return await TryCopyToMemoryStreamAsync(result.Content, args.CancellationToken); return result.ResponseStream;
} }
protected virtual string GetContainerName(BlobProviderArgs args) protected virtual string GetContainerName(BlobProviderArgs args)

2
framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/AwsBlobProvider.cs

@ -103,7 +103,7 @@ public class AwsBlobProvider : BlobProviderBase, ITransientDependency
Key = blobName Key = blobName
}); });
return await TryCopyToMemoryStreamAsync(response.ResponseStream, args.CancellationToken); return response.ResponseStream;
} }
} }

3
framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs

@ -66,8 +66,7 @@ public class AzureBlobProvider : BlobProviderBase, ITransientDependency
} }
var blobClient = GetBlobClient(args, blobName); var blobClient = GetBlobClient(args, blobName);
var download = await blobClient.DownloadAsync(); return await blobClient.OpenReadAsync(cancellationToken: args.CancellationToken);
return await TryCopyToMemoryStreamAsync(download.Value.Content, args.CancellationToken);
} }
protected virtual BlobClient GetBlobClient(BlobProviderArgs args, string blobName) protected virtual BlobClient GetBlobClient(BlobProviderArgs args, string blobName)

8
framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProvider.cs

@ -70,13 +70,7 @@ public class FileSystemBlobProvider : BlobProviderBase, ITransientDependency
return await Policy.Handle<IOException>() return await Policy.Handle<IOException>()
.WaitAndRetryAsync(2, retryCount => TimeSpan.FromSeconds(retryCount)) .WaitAndRetryAsync(2, retryCount => TimeSpan.FromSeconds(retryCount))
.ExecuteAsync(async () => .ExecuteAsync(() => Task.FromResult(File.OpenRead(filePath)));
{
using (var fileStream = File.OpenRead(filePath))
{
return await TryCopyToMemoryStreamAsync(fileStream, args.CancellationToken);
}
});
} }
protected virtual Task<bool> ExistsAsync(string filePath) protected virtual Task<bool> ExistsAsync(string filePath)

17
framework/src/Volo.Abp.Imaging.ImageSharp/Volo/Abp/Imaging/ImageSharpImageCompressorContributor.cs

@ -5,9 +5,6 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using SixLabors.ImageSharp; using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Formats.Webp;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Http; using Volo.Abp.Http;
@ -32,7 +29,7 @@ public class ImageSharpImageCompressorContributor : IImageCompressorContributor,
return new ImageCompressResult<Stream>(stream, ImageProcessState.Unsupported); return new ImageCompressResult<Stream>(stream, ImageProcessState.Unsupported);
} }
var image = await Image.LoadAsync(stream, cancellationToken); using var image = await Image.LoadAsync(stream, cancellationToken);
if (!CanCompress(image.Metadata.DecodedImageFormat!.DefaultMimeType)) if (!CanCompress(image.Metadata.DecodedImageFormat!.DefaultMimeType))
{ {
@ -46,7 +43,7 @@ public class ImageSharpImageCompressorContributor : IImageCompressorContributor,
return new ImageCompressResult<Stream>(memoryStream, ImageProcessState.Done); return new ImageCompressResult<Stream>(memoryStream, ImageProcessState.Done);
} }
memoryStream.Dispose(); await memoryStream.DisposeAsync();
return new ImageCompressResult<Stream>(stream, ImageProcessState.Canceled); return new ImageCompressResult<Stream>(stream, ImageProcessState.Canceled);
} }
@ -69,7 +66,7 @@ public class ImageSharpImageCompressorContributor : IImageCompressorContributor,
} }
var newBytes = await result.Result.GetAllBytesAsync(cancellationToken); var newBytes = await result.Result.GetAllBytesAsync(cancellationToken);
result.Result.Dispose(); await result.Result.DisposeAsync();
return new ImageCompressResult<byte[]>(newBytes, result.State); return new ImageCompressResult<byte[]>(newBytes, result.State);
} }
@ -100,7 +97,7 @@ public class ImageSharpImageCompressorContributor : IImageCompressorContributor,
} }
catch catch
{ {
memoryStream.Dispose(); await memoryStream.DisposeAsync();
throw; throw;
} }
} }
@ -110,11 +107,11 @@ public class ImageSharpImageCompressorContributor : IImageCompressorContributor,
switch (format.DefaultMimeType) switch (format.DefaultMimeType)
{ {
case MimeTypes.Image.Jpeg: case MimeTypes.Image.Jpeg:
return Options.JpegEncoder ?? new JpegEncoder(); return Options.JpegEncoder;
case MimeTypes.Image.Png: case MimeTypes.Image.Png:
return Options.PngEncoder ?? new PngEncoder(); return Options.PngEncoder;
case MimeTypes.Image.Webp: case MimeTypes.Image.Webp:
return Options.WebpEncoder ?? new WebpEncoder(); return Options.WebpEncoder;
default: default:
throw new NotSupportedException($"No encoder available for the given format: {format.Name}"); throw new NotSupportedException($"No encoder available for the given format: {format.Name}");
} }

6
framework/src/Volo.Abp.Imaging.ImageSharp/Volo/Abp/Imaging/ImageSharpImageResizerContributor.cs

@ -23,7 +23,7 @@ public class ImageSharpImageResizerContributor : IImageResizerContributor, ITran
return new ImageResizeResult<Stream>(stream, ImageProcessState.Unsupported); return new ImageResizeResult<Stream>(stream, ImageProcessState.Unsupported);
} }
var image = await Image.LoadAsync(stream, cancellationToken); using var image = await Image.LoadAsync(stream, cancellationToken);
if (!CanResize(image.Metadata.DecodedImageFormat!.DefaultMimeType)) if (!CanResize(image.Metadata.DecodedImageFormat!.DefaultMimeType))
{ {
@ -49,7 +49,7 @@ public class ImageSharpImageResizerContributor : IImageResizerContributor, ITran
} }
catch catch
{ {
memoryStream.Dispose(); await memoryStream.DisposeAsync();
throw; throw;
} }
} }
@ -76,7 +76,7 @@ public class ImageSharpImageResizerContributor : IImageResizerContributor, ITran
var newBytes = await result.Result.GetAllBytesAsync(cancellationToken); var newBytes = await result.Result.GetAllBytesAsync(cancellationToken);
result.Result.Dispose(); await result.Result.DisposeAsync();
return new ImageResizeResult<byte[]>(newBytes, result.State); return new ImageResizeResult<byte[]>(newBytes, result.State);
} }

43
framework/src/Volo.Abp.Imaging.SkiaSharp/Volo/Abp/Imaging/SkiaSharpImageResizerContributor.cs

@ -25,21 +25,19 @@ public class SkiaSharpImageResizerContributor : IImageResizerContributor, ITrans
return new ImageResizeResult<byte[]>(bytes, ImageProcessState.Unsupported); return new ImageResizeResult<byte[]>(bytes, ImageProcessState.Unsupported);
} }
using (var memoryStream = new MemoryStream(bytes)) using var memoryStream = new MemoryStream(bytes);
{ var result = await TryResizeAsync(memoryStream, resizeArgs, mimeType, cancellationToken);
var result = await TryResizeAsync(memoryStream, resizeArgs, mimeType, cancellationToken);
if (result.State != ImageProcessState.Done) if (result.State != ImageProcessState.Done)
{ {
return new ImageResizeResult<byte[]>(bytes, result.State); return new ImageResizeResult<byte[]>(bytes, result.State);
} }
var newBytes = await result.Result.GetAllBytesAsync(cancellationToken); var newBytes = await result.Result.GetAllBytesAsync(cancellationToken);
result.Result.Dispose(); result.Result.Dispose();
return new ImageResizeResult<byte[]>(newBytes, result.State); return new ImageResizeResult<byte[]>(newBytes, result.State);
}
} }
public virtual async Task<ImageResizeResult<Stream>> TryResizeAsync(Stream stream, ImageResizeArgs resizeArgs, string? mimeType = null, CancellationToken cancellationToken = default) public virtual async Task<ImageResizeResult<Stream>> TryResizeAsync(Stream stream, ImageResizeArgs resizeArgs, string? mimeType = null, CancellationToken cancellationToken = default)
@ -51,21 +49,14 @@ public class SkiaSharpImageResizerContributor : IImageResizerContributor, ITrans
var (memoryBitmapStream, memorySkCodecStream) = await CreateMemoryStream(stream); var (memoryBitmapStream, memorySkCodecStream) = await CreateMemoryStream(stream);
using (var original = SKBitmap.Decode(memoryBitmapStream)) using var original = SKBitmap.Decode(memoryBitmapStream);
{ using var resized = original.Resize(new SKImageInfo(resizeArgs.Width, resizeArgs.Height), Options.SKFilterQuality);
using (var resized = original.Resize(new SKImageInfo(resizeArgs.Width, resizeArgs.Height), Options.SKFilterQuality)) using var image = SKImage.FromBitmap(resized);
{ using var codec = SKCodec.Create(memorySkCodecStream);
using (var image = SKImage.FromBitmap(resized)) var memoryStream = new MemoryStream();
{ using var skData = image.Encode(codec.EncodedFormat, Options.Quality);
using (var codec = SKCodec.Create(memorySkCodecStream)) skData.SaveTo(memoryStream);
{ return new ImageResizeResult<Stream>(memoryStream, ImageProcessState.Done);
var memoryStream = new MemoryStream();
image.Encode(codec.EncodedFormat, Options.Quality).SaveTo(memoryStream);
return new ImageResizeResult<Stream>(memoryStream, ImageProcessState.Done);
}
}
}
}
} }
protected virtual async Task<(MemoryStream, MemoryStream)> CreateMemoryStream(Stream stream) protected virtual async Task<(MemoryStream, MemoryStream)> CreateMemoryStream(Stream stream)

Loading…
Cancel
Save