我有一些代码可以获取上传的图像,将其大小调整为5种不同的大小,然后将这些代码上传到另一个存储库。我正在尝试使用TPL并行执行5个图像大小调整操作。
Upfront我会提到resizing函数是一个静态方法,但它不使用任何静态资源(所以多个并行调用不应该相互踩,从我所知道的)。 非常相关的是,这是在ASP.NET的上下文中,它有一些不同的线程问题。
当我运行以下代码时,我总是从其中一个调用中得到一个“无效参数”错误,尽管哪个调用有所不同:
tasks = new Task<Uri>[]
{
Task.Run<Uri>(() => Upload(intId, ProfilePhotoSize.FiveHundredFixedWidth, photoStream, mediaType, minWidth)),
Task.Run<Uri>(() => Upload(intId, ProfilePhotoSize.Square220, photoStream, mediaType, minWidth)),
Task.Run<Uri>(() => Upload(intId, ProfilePhotoSize.Square140, photoStream, mediaType, minWidth)),
Task.Run<Uri>(() => Upload(intId, ProfilePhotoSize.Square80, photoStream, mediaType, minWidth)),
Task.Run<Uri>(() => Upload(intId, ProfilePhotoSize.Square50, photoStream, mediaType, minWidth))
};
await Task.WhenAll(tasks)
如果我查看创建的图像,有些图像会正常,有些图像会明显损坏 - 这不仅适用于“错误”图像。
然而,同步执行这五个操作会产生五个好的图像:
Upload(intId, ProfilePhotoSize.FiveHundredFixedWidth, photoStream, mediaType, minWidth);
Upload(intId, ProfilePhotoSize.Square220, photoStream, mediaType, minWidth);
Upload(intId, ProfilePhotoSize.Square140, photoStream, mediaType, minWidth);
Upload(intId, ProfilePhotoSize.Square80, photoStream, mediaType, minWidth);
Upload(intId, ProfilePhotoSize.Square50, photoStream, mediaType, minWidth);
这些操作是否存在已知问题,或者我可能做了其他可能造成这种情况的狡猾问题?
这是图像大小调整功能:
private static Stream Resize(Stream image, ResizeParameters parameters, ImageUtility.ResizeType type)
{
Image image1 = (Image) new Bitmap(image);
Image image2 = (Image) null;
Image image3 = (Image) null;
Graphics graphics = (Graphics) null;
MemoryStream memoryStream = new MemoryStream();
try
{
parameters = ImageUtility.CalculateSize(image1, parameters, type);
if (!parameters.DoNothing)
{
image2 = (Image) new Bitmap(parameters.Width, parameters.Height);
switch (type)
{
case ImageUtility.ResizeType.FixedWidth:
graphics = Graphics.FromImage(image2);
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.FillRectangle(Brushes.White, 0, 0, image1.Width, image1.Height);
graphics.DrawImage(image1, 0, 0, parameters.Width, parameters.Height);
graphics.Dispose();
break;
case ImageUtility.ResizeType.PaddingSquare:
image3 = (Image) new Bitmap(parameters.SelectedWidth, parameters.SelectedHeight);
graphics = Graphics.FromImage(image3);
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.FillRectangle(Brushes.White, 0, 0, parameters.SelectedWidth, parameters.SelectedHeight);
graphics.DrawImage(image1, parameters.X, parameters.Y, image1.Width, image1.Height);
graphics = Graphics.FromImage(image2);
graphics.DrawImage(image3, 0, 0, parameters.Width, parameters.Height);
graphics.Dispose();
break;
case ImageUtility.ResizeType.CropSquare:
image3 = (Image) new Bitmap(parameters.SelectedWidth, parameters.SelectedHeight);
graphics = Graphics.FromImage(image3);
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.FillRectangle(Brushes.White, 0, 0, parameters.SelectedWidth, parameters.SelectedHeight);
graphics.DrawImage(image1, new Rectangle(0, 0, parameters.SelectedWidth, parameters.SelectedHeight), parameters.X, parameters.Y, image3.Width, image3.Height, GraphicsUnit.Pixel);
graphics = Graphics.FromImage(image2);
graphics.DrawImage(image3, 0, 0, parameters.Width, parameters.Height);
graphics.Dispose();
break;
}
EncoderParameter encoderParameter = new EncoderParameter(Encoder.Quality, 90L);
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = encoderParameter;
image2.Save((Stream) memoryStream, ImageUtility.GetEncoder(parameters.Format), encoderParams);
}
else
{
image.Seek(0L, SeekOrigin.Begin);
image.CopyTo((Stream) memoryStream);
}
memoryStream.Seek(0L, SeekOrigin.Begin);
return (Stream) memoryStream;
}
finally
{
image1.Dispose();
if (image2 != null)
image2.Dispose();
if (image3 != null)
image3.Dispose();
if (graphics != null)
graphics.Dispose();
}
}