Browse Source

async await where required

pull/1574/head
James Jackson-South 6 years ago
parent
commit
dd9aa7908e
  1. 6
      src/ImageSharp/Advanced/AdvancedImageExtensions.cs
  2. 4
      src/ImageSharp/Formats/Bmp/BmpEncoder.cs
  3. 4
      src/ImageSharp/Formats/Gif/GifEncoder.cs
  4. 4
      src/ImageSharp/Formats/Tga/TgaDecoder.cs
  5. 4
      src/ImageSharp/Formats/Tga/TgaEncoder.cs
  6. 11
      src/ImageSharp/Image.Decode.cs
  7. 67
      src/ImageSharp/Image.FromStream.cs
  8. 15
      src/ImageSharp/Image.cs

6
src/ImageSharp/Advanced/AdvancedImageExtensions.cs

@ -4,8 +4,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using SixLabors.ImageSharp.Formats;
@ -76,8 +74,8 @@ namespace SixLabors.ImageSharp.Advanced
/// <param name="source">The source.</param>
/// <param name="visitor">The visitor.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public static Task AcceptVisitorAsync(this Image source, IImageVisitorAsync visitor)
=> source.AcceptAsync(visitor);
public static async Task AcceptVisitorAsync(this Image source, IImageVisitorAsync visitor)
=> await source.AcceptAsync(visitor).ConfigureAwait(false);
/// <summary>
/// Gets the configuration for the image.

4
src/ImageSharp/Formats/Bmp/BmpEncoder.cs

@ -42,11 +42,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp
}
/// <inheritdoc/>
public Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream)
public async Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream)
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new BmpEncoderCore(this, image.GetMemoryAllocator());
return encoder.EncodeAsync(image, stream);
await encoder.EncodeAsync(image, stream).ConfigureAwait(false);
}
}
}

4
src/ImageSharp/Formats/Gif/GifEncoder.cs

@ -41,11 +41,11 @@ namespace SixLabors.ImageSharp.Formats.Gif
}
/// <inheritdoc/>
public Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream)
public async Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream)
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new GifEncoderCore(image.GetConfiguration(), this);
return encoder.EncodeAsync(image, stream);
await encoder.EncodeAsync(image, stream).ConfigureAwait(false);
}
}
}

4
src/ImageSharp/Formats/Tga/TgaDecoder.cs

@ -74,11 +74,11 @@ namespace SixLabors.ImageSharp.Formats.Tga
}
/// <inheritdoc/>
public Task<IImageInfo> IdentifyAsync(Configuration configuration, Stream stream)
public async Task<IImageInfo> IdentifyAsync(Configuration configuration, Stream stream)
{
Guard.NotNull(stream, nameof(stream));
return new TgaDecoderCore(configuration, this).IdentifyAsync(stream);
return await new TgaDecoderCore(configuration, this).IdentifyAsync(stream).ConfigureAwait(false);
}
}
}

4
src/ImageSharp/Formats/Tga/TgaEncoder.cs

@ -32,11 +32,11 @@ namespace SixLabors.ImageSharp.Formats.Tga
}
/// <inheritdoc/>
public Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream)
public async Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream)
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new TgaEncoderCore(this, image.GetMemoryAllocator());
return encoder.EncodeAsync(image, stream);
await encoder.EncodeAsync(image, stream).ConfigureAwait(false);
}
}
}

11
src/ImageSharp/Image.Decode.cs

@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp
/// <returns>The mime type or null if none found.</returns>
private static Task<IImageFormat> InternalDetectFormatAsync(Stream stream, Configuration config)
{
// we are going to cheat here because we know that by this point we have been wrapped in a
// We are going to cheat here because we know that by this point we have been wrapped in a
// seekable stream then we are free to use sync APIs this is potentially brittle and may
// need a better fix in the future.
return Task.FromResult(InternalDetectFormat(stream, config));
@ -184,7 +184,7 @@ namespace SixLabors.ImageSharp
return (null, null);
}
var info = detector?.Identify(config, stream);
IImageInfo info = detector?.Identify(config, stream);
return new FormattedImageInfo(info, format);
}
@ -203,7 +203,12 @@ namespace SixLabors.ImageSharp
return (null, null);
}
var info = await detector?.IdentifyAsync(config, stream);
if (detector is null)
{
return (null, format);
}
IImageInfo info = await detector.IdentifyAsync(config, stream).ConfigureAwait(false);
return new FormattedImageInfo(info, format);
}
}

67
src/ImageSharp/Image.FromStream.cs

@ -57,8 +57,12 @@ namespace SixLabors.ImageSharp
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <returns>The format type or null if none found.</returns>
public static Task<IImageFormat> DetectFormatAsync(Configuration configuration, Stream stream)
=> WithSeekableStreamAsync(configuration, stream, s => InternalDetectFormatAsync(s, configuration));
public static async Task<IImageFormat> DetectFormatAsync(Configuration configuration, Stream stream)
=> await WithSeekableStreamAsync(
configuration,
stream,
async s => await InternalDetectFormatAsync(s, configuration).ConfigureAwait(false))
.ConfigureAwait(false);
/// <summary>
/// Reads the raw image information from the specified stream without fully decoding it.
@ -180,8 +184,12 @@ namespace SixLabors.ImageSharp
/// <returns>
/// The <see cref="FormattedImageInfo"/> with <see cref="FormattedImageInfo.ImageInfo"/> set to null if suitable info detector is not found.
/// </returns>
public static Task<FormattedImageInfo> IdentifyWithFormatAsync(Configuration configuration, Stream stream)
=> WithSeekableStreamAsync(configuration, stream, s => InternalIdentityAsync(s, configuration ?? Configuration.Default));
public static async Task<FormattedImageInfo> IdentifyWithFormatAsync(Configuration configuration, Stream stream)
=> await WithSeekableStreamAsync(
configuration,
stream,
async s => await InternalIdentityAsync(s, configuration ?? Configuration.Default))
.ConfigureAwait(false);
/// <summary>
/// Decode a new instance of the <see cref="Image"/> class from the given stream.
@ -330,7 +338,7 @@ namespace SixLabors.ImageSharp
/// <returns>A new <see cref="Image"/>.</returns>>
public static async Task<Image> LoadAsync(Configuration configuration, Stream stream)
{
var fmt = await LoadWithFormatAsync(configuration, stream).ConfigureAwait(false);
FormattedImage fmt = await LoadWithFormatAsync(configuration, stream).ConfigureAwait(false);
return fmt.Image;
}
@ -387,9 +395,9 @@ namespace SixLabors.ImageSharp
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public static Task<FormattedImage<TPixel>> LoadWithFormatAsync<TPixel>(Stream stream)
public static async Task<FormattedImage<TPixel>> LoadWithFormatAsync<TPixel>(Stream stream)
where TPixel : unmanaged, IPixel<TPixel>
=> LoadWithFormatAsync<TPixel>(Configuration.Default, stream);
=> await LoadWithFormatAsync<TPixel>(Configuration.Default, stream).ConfigureAwait(false);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given stream.
@ -417,9 +425,13 @@ namespace SixLabors.ImageSharp
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
public static Task<Image<TPixel>> LoadAsync<TPixel>(Stream stream, IImageDecoder decoder)
public static async Task<Image<TPixel>> LoadAsync<TPixel>(Stream stream, IImageDecoder decoder)
where TPixel : unmanaged, IPixel<TPixel>
=> WithSeekableStreamAsync(Configuration.Default, stream, s => decoder.DecodeAsync<TPixel>(Configuration.Default, s));
=> await WithSeekableStreamAsync(
Configuration.Default,
stream,
async s => await decoder.DecodeAsync<TPixel>(Configuration.Default, s).ConfigureAwait(false))
.ConfigureAwait(false);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given stream.
@ -451,9 +463,13 @@ namespace SixLabors.ImageSharp
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
public static Task<Image<TPixel>> LoadAsync<TPixel>(Configuration configuration, Stream stream, IImageDecoder decoder)
public static async Task<Image<TPixel>> LoadAsync<TPixel>(Configuration configuration, Stream stream, IImageDecoder decoder)
where TPixel : unmanaged, IPixel<TPixel>
=> WithSeekableStreamAsync(configuration, stream, s => decoder.DecodeAsync<TPixel>(configuration, s));
=> await WithSeekableStreamAsync(
configuration,
stream,
async s => await decoder.DecodeAsync<TPixel>(configuration, s).ConfigureAwait(false))
.ConfigureAwait(false);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given stream.
@ -520,7 +536,11 @@ namespace SixLabors.ImageSharp
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static async Task<FormattedImage> LoadWithFormatAsync(Configuration configuration, Stream stream)
{
(Image img, IImageFormat format) data = await WithSeekableStreamAsync(configuration, stream, s => DecodeAsync(s, configuration));
(Image img, IImageFormat format) data = await WithSeekableStreamAsync(
configuration,
stream,
async s => await DecodeAsync(s, configuration).ConfigureAwait(false))
.ConfigureAwait(false);
if (data.img != null)
{
@ -553,7 +573,12 @@ namespace SixLabors.ImageSharp
public static async Task<FormattedImage<TPixel>> LoadWithFormatAsync<TPixel>(Configuration configuration, Stream stream)
where TPixel : unmanaged, IPixel<TPixel>
{
(Image<TPixel> img, IImageFormat format) data = await WithSeekableStreamAsync(configuration, stream, s => DecodeAsync<TPixel>(s, configuration));
(Image<TPixel> img, IImageFormat format) data =
await WithSeekableStreamAsync(
configuration,
stream,
async s => await DecodeAsync<TPixel>(s, configuration).ConfigureAwait(false))
.ConfigureAwait(false);
if (data.img != null)
{
@ -646,6 +671,9 @@ namespace SixLabors.ImageSharp
}
// We want to be able to load images from things like HttpContext.Request.Body
// TODO: Should really find a nice way to use a pool for these.
// Investigate readonly version of the linked implementation.
// https://github.com/mgravell/Pipelines.Sockets.Unofficial/compare/mgravell:24482d4...mgravell:6740ea4
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
@ -655,7 +683,10 @@ namespace SixLabors.ImageSharp
}
}
private static async Task<T> WithSeekableStreamAsync<T>(Configuration configuration, Stream stream, Func<Stream, Task<T>> action)
private static async Task<T> WithSeekableStreamAsync<T>(
Configuration configuration,
Stream stream,
Func<Stream, Task<T>> action)
{
Guard.NotNull(configuration, nameof(configuration));
Guard.NotNull(stream, nameof(stream));
@ -665,8 +696,9 @@ namespace SixLabors.ImageSharp
throw new NotSupportedException("Cannot read from the stream.");
}
// to make sure we don't trigger anything with aspnetcore then we just need to make sure we are seekable and we make the copy using CopyToAsync
// if the stream is seekable then we arn't using one of the aspnetcore wrapped streams that error on sync api calls and we can use it with out
// To make sure we don't trigger anything with aspnetcore then we just need to make sure we are
// seekable and we make the copy using CopyToAsync if the stream is seekable then we arn't using
// one of the aspnetcore wrapped streams that error on sync api calls and we can use it without
// having to further wrap
if (stream.CanSeek)
{
@ -678,7 +710,8 @@ namespace SixLabors.ImageSharp
return await action(stream).ConfigureAwait(false);
}
using (var memoryStream = new MemoryStream()) // should really find a nice way to use a pool for these!!
// TODO: See above comment.
using (var memoryStream = new MemoryStream())
{
await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
memoryStream.Position = 0;

15
src/ImageSharp/Image.cs

@ -105,13 +105,13 @@ namespace SixLabors.ImageSharp
/// <param name="encoder">The encoder to save the image with.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the stream or encoder is null.</exception>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public Task SaveAsync(Stream stream, IImageEncoder encoder)
public async Task SaveAsync(Stream stream, IImageEncoder encoder)
{
Guard.NotNull(stream, nameof(stream));
Guard.NotNull(encoder, nameof(encoder));
this.EnsureNotDisposed();
return this.AcceptVisitorAsync(new EncodeVisitor(encoder, stream));
await this.AcceptVisitorAsync(new EncodeVisitor(encoder, stream)).ConfigureAwait(false);
}
/// <summary>
@ -177,16 +177,11 @@ namespace SixLabors.ImageSharp
}
public void Visit<TPixel>(Image<TPixel> image)
where TPixel : unmanaged, IPixel<TPixel>
{
this.encoder.Encode(image, this.stream);
}
where TPixel : unmanaged, IPixel<TPixel> => this.encoder.Encode(image, this.stream);
public Task VisitAsync<TPixel>(Image<TPixel> image)
public async Task VisitAsync<TPixel>(Image<TPixel> image)
where TPixel : unmanaged, IPixel<TPixel>
{
return this.encoder.EncodeAsync(image, this.stream).ConfigureAwait(false);
}
=> await this.encoder.EncodeAsync(image, this.stream).ConfigureAwait(false);
}
}
}

Loading…
Cancel
Save