Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 异步上载多个图像并调整其大小时出现内存不足异常_C#_Asp.net Mvc_Asynchronous_Async Await_Azure Storage Blobs - Fatal编程技术网

C# 异步上载多个图像并调整其大小时出现内存不足异常

C# 异步上载多个图像并调整其大小时出现内存不足异常,c#,asp.net-mvc,asynchronous,async-await,azure-storage-blobs,C#,Asp.net Mvc,Asynchronous,Async Await,Azure Storage Blobs,您好,我正在尝试异步上传一些图像,我遇到内存不足异常,我正在使用语句进行处理,但我得到以下堆栈跟踪 [OutOfMemoryException: Out of memory.] System.Drawing.Graphics.CheckErrorStatus(Int32 status) +1146420 System.Drawing.Graphics.DrawImage(Image image, Rectangle destRect, Int32 srcX, Int32 srcY,

您好,我正在尝试异步上传一些图像,我遇到内存不足异常,我正在使用语句进行处理,但我得到以下堆栈跟踪

[OutOfMemoryException: Out of memory.]
   System.Drawing.Graphics.CheckErrorStatus(Int32 status) +1146420
   System.Drawing.Graphics.DrawImage(Image image, Rectangle destRect, Int32 srcX, Int32 srcY, Int32 srcWidth, Int32 srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttrs, DrawImageAbort callback, IntPtr callbackData) +256
   System.Drawing.Graphics.DrawImage(Image image, Rectangle destRect, Int32 srcX, Int32 srcY, Int32 srcWidth, Int32 srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttr) +48
这是resizer,在这里我得到异常:

public Bitmap ResizeImage(Image image, int width, int height)
        {
          var newWidth = (int)(imageWidth * ratio) < 210 ? 210 : (int)(imageWidth * ratio);
          var newHeight = (int)(imageHeight * ratio) < 210 ? 210 : (int)(imageHeight * ratio);
            //Image resize logic

            var destRect = new Rectangle(0, 0, newWidth, newHeight);
            var destImage = new Bitmap(newWidth, newHeight);
            destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

            using (var graphics = Graphics.FromImage(destImage))
            {
                graphics.CompositingMode = CompositingMode.SourceCopy;
                graphics.CompositingQuality = CompositingQuality.HighQuality;
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = SmoothingMode.HighQuality;
                graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

                using (var wrapMode = new ImageAttributes())
                {
                    wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                    /*Here I get error*/graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel,
                        wrapMode);
                }
            }

            return destImage;
        }
公共位图大小图像(图像图像、整数宽度、整数高度)
{
var newWidth=(int)(图像宽度*比率)<210?210:(int)(图像宽度*比率);
var newHeight=(int)(图像高度*比率)<210?210:(int)(图像高度*比率);
//图像调整逻辑
var destect=新矩形(0,0,newWidth,newHeight);
var destImage=新位图(新宽度、新高度);
Destinmage.SetResolution(图像.水平分辨率,图像.垂直分辨率);
使用(var graphics=graphics.FromImage(destImage))
{
graphics.CompositingMode=CompositingMode.SourceCopy;
graphics.CompositingQuality=CompositingQuality.HighQuality;
graphics.InterpolationMode=InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode=SmoothingMode.HighQuality;
graphics.PixelOffsetMode=PixelOffsetMode.HighQuality;
使用(var wrapMode=newImageAttributes())
{
wrapMode.SetWrapMode(wrapMode.TileFlipXY);
/*这里我得到错误*/graphics.DrawImage(image,desect,0,0,image.Width,image.Height,GraphicsUnit.Pixel,
wrapMode);
}
}
返回目标图像;
}
此处是上载图像的位置:

private async Task<short> UploadImage(string title, HttpPostedFileBase file, short dimensionWidth,
            short dimensionHeight)
        {
            var blockBlob = CloudBlobContainer.GetBlockBlobReference(title);
            var jpgInfo = ImageCodecInfo.GetImageEncoders().First(codecInfo => codecInfo.MimeType == "image/jpeg");
            using (var image = Image.FromStream(file.InputStream, true, true))
            {
                using (var stream = new MemoryStream())
                using (var encParams = new EncoderParameters(1))
                {
                    encParams.Param[0] = new EncoderParameter(Encoder.Quality, 60L);
                    if (image.Width > dimensionWidth && image.Height > dimensionHeight)
                        using (Bitmap bitMapImage = ResizeImage(image, dimensionWidth, dimensionHeight))
                        {
                            bitMapImage.Save(stream, jpgInfo, encParams);
                        }
                    else
                    {
                        image.Save(stream, jpgInfo, encParams);
                    }
                    stream.Position = 0;
                    await blockBlob.UploadFromStreamAsync(stream);
                    blockBlob.Properties.CacheControl = "public, max-age=864000";
                    blockBlob.SetProperties();
                }
            }
            return (short)EnumData.EOpStatus.Success;
        }
private async Task UploadImage(字符串标题、HttpPostedFileBase文件、短维度宽度、,
短尺寸(高度)
{
var blockBlob=CloudBlobContainer.getblockblobbreference(title);
var jpgInfo=ImageCodecInfo.GetImageEncoders().First(codecInfo=>codecInfo.MimeType==“image/jpeg”);
使用(var image=image.FromStream(file.InputStream,true,true))
{
使用(var stream=new MemoryStream())
使用(var encParams=新编码器参数(1))
{
encParams.Param[0]=新编码器参数(编码器质量,60L);
if(image.Width>dimensionWidth&&image.Height>dimensionHeight)
使用(位图bitMapImage=ResizeImage(图像、尺寸宽度、尺寸高度))
{
保存(流、jpgInfo、encParams);
}
其他的
{
保存(流、jpgInfo、encParams);
}
流位置=0;
等待blockBlob.UploadFromStreamAsync(流);
blockBlob.Properties.CacheControl=“public,最大年限=864000”;
blockBlob.SetProperties();
}
}
返回(短)EnumData.EOpStatus.Success;
}
主要功能如下:

        public async Task<string> UploadImages(string title, IEnumerable<HttpPostedFileBase> files, short fileCount)
        {
            var fileIndex = 0;
            var imageCsv = String.Empty;
            var uploadTask = new Task<short>[fileCount * 2];
            foreach (var file in files)
            {
                var fullTitle = title + "-" + Convert.ToString(fileIndex) + Path.GetExtension(file.FileName);
                uploadTask[fileIndex] = UploadImage(fullTitle, file, 1440, 900);
                uploadTask[fileIndex + 1] = UploadImage("thumb-" + fullTitle, file, 280, 280);
                imageCsv += String.IsNullOrEmpty(imageCsv) ? fullTitle : "," + fullTitle;
                /*await Task.WhenAll(uploadTask[fileIndex], uploadTask[fileIndex + 1]);*///Works fine in this case 

                fileIndex += 2;
            }
            await Task.WhenAll(uploadTask);
            return imageCsv;
        }
公共异步任务上载映像(字符串标题、IEnumerable文件、短文件计数)
{
var fileIndex=0;
var imageCsv=String.Empty;
var uploadTask=新任务[fileCount*2];
foreach(文件中的var文件)
{
var fullTitle=title+“-”+Convert.ToString(fileIndex)+Path.GetExtension(file.FileName);
uploadTask[fileIndex]=UploadImage(完整标题,文件,1440900);
uploadTask[fileIndex+1]=UploadImage(“thumb-”+fullTitle,文件,280280);
imageCsv+=String.IsNullOrEmpty(imageCsv)?fullTitle:“,”+fullTitle;
/*wait Task.whalll(uploadTask[fileIndex],uploadTask[fileIndex+1]);*///在这种情况下可以正常工作
fileIndex+=2;
}
等待任务。WhenAll(上传任务);
返回图像CSV;
}
所以在一些上传之后,我得到了一个错误

性能监视器在整个应用程序使用过程中似乎都很正常,我认为它很正常

我相信您确实在尝试在目标矩形之外绘制。。。如果您注意到您的代码,您实际上(在标记的行中)正在绘制
image.Width
image.Height
(原始尺寸),而不是应用的维度比率…

在作业完成后处理sourceImage和DesImage。

是否尝试运行Visual Studio的内存分析工具?这可能不是实际的OOM错误。GDI+喜欢在传递无效参数时返回这样的错误。@Micky nope现在尝试使用性能监视器,但这提醒了我-GDI对象有一个限制,不管您有多少可用RAM。虽然在使用GDI(位图只是其包装器)时,您似乎在管理它们方面做得相当好,
OutOfMemoryException
最好命名为
outofhandleexception
OutOfUnManagedMemoryException
,但它通常与CLR分配的#字节无关。这都是非托管内存和GDI句柄。然而,查看您的代码,我没有看到任何明显的错误会导致内存或句柄泄漏。你是在处理非常大的图像吗?我想你是在拍摄drawImage?我们应该从整个图像而不是固定的图像中进行绘制,出于好奇,这里请查看链接,只需尝试
graphics.DrawImage(图像,析取,0,0,50,50,GraphicsUnit.Pixel,wrapMode)但是我建议的固定大小呢?同样的例外?你尝试了固定尺寸,即200、50和正常尺寸。你的答案在我看来还行,但你能解释一下为什么这样做,或者提供一个代码片段如何做到这一点吗?这将使这篇文章的未来访问者更容易找到他们的解决方案。谢谢