簡體   English   中英

天藍色函數 c# .net 中的 DrawingCore 異常

[英]DrawingCore exception in azure function c# .net

未處理的異常: System.MemberAccessException

Object is busy and cannot state allow this operation [GDI+ status: ObjectBusy]
       at System.DrawingCore.GDIPlus.CheckStatus(Status status)
       at System.DrawingCore.Image.Dispose(Boolean disposing)
       at System.DrawingCore.Image.Finalize()

以下代碼偶爾會發生此錯誤。 我正在使用 sautinsoft 庫,而 imageFormat 是 System.DrawingCore.Imaging。

  using (Stream fs = pdfFile.OpenReadStream())
      {
        await Task.Run(() => _pdfFocus.OpenPdf(fs));
        if (_pdfFocus.PageCount > 0)
          {
            _pdfFocus.ImageOptions.ImageFormat = imageFormat;
            _pdfFocus.ImageOptions.Dpi = 100;
            _pdfFocus.ImageOptions.JpegQuality = 90;
            for (int i = 1; i <= _pdfFocus.PageCount; i++)
              {
                 await Task.Run(() => pdfPagesAsImageFileList.Add(_pdfFocus.ToImage(i)));
              }
            }
         Task.WaitAll();
       }

就像 Marc 所說的 azure 有沙箱限制,並且大多數將 pdf 轉換為圖像的 .net 包需要 GDI,這不受支持。 現在我只找到一個包來使用 .net 來實現它。 您可以嘗試使用GhostScriptMagick.NET-Q16-AnyCPU來實現它。

安裝Ghostscript ,您將在 bin 文件夾中獲得gsdll32.dll文件。 下面是我的測試代碼,將02.pdfgsdll32.dll復制到kudu wwwroot文件夾下。

using System.Net.Http;
using ImageMagick;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;

namespace FunctionApp6
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static void Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log,ExecutionContext context)
        {
            log.Info("C# HTTP trigger function processed a request.");

            MagickNET.SetGhostscriptDirectory(context.FunctionAppDirectory);
            log.Info(context.FunctionAppDirectory);
            MagickReadSettings settings = new MagickReadSettings();
            // Settings the density to 300 dpi will create an image with a better quality
            settings.Density = new Density(300, 300);

            using (MagickImageCollection images = new MagickImageCollection())
            {
                log.Info(context.FunctionAppDirectory + "\\02.pdf");
                // Add all the pages of the pdf file to the collection
                images.Read(context.FunctionAppDirectory+"\\02.pdf", settings);

                int page = 1;
                foreach (MagickImage image in images)
                {
                    log.Info(context.FunctionAppDirectory + "\\outpng" + page + ".png");
                    // Write page to file that contains the page number
                    image.Write(context.FunctionAppDirectory + "\\outpng" + page + ".png");
                    // Writing to a specific format works the same as for a single image
                    //image.Format = MagickFormat.Ptif;
                    //image.Write(SampleFiles.OutputDirectory + "Snakeware.Page" + page + ".tif");
                    page++;
                }
            }

            log.Info("convert finish");
        }
    }
}

這是天藍色的結果圖片。

在此處輸入圖片說明

Azure Functions 在安全環境(也稱為沙箱)中運行。 這個沙箱有很多限制,所有限制都在這里描述: https : //github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox

在您的特定情況下,您受到限制,因為該過程無法訪問上面鏈接的頁面中提到的 GDI32:

為了徹底減少攻擊面,沙箱阻止了幾乎所有的 Win32k.sys API 被調用,這實際上意味着大部分 User32/GDI32 系統調用被阻止。 對於大多數應用程序,這不是問題,因為大多數 Azure Web 應用程序不需要訪問 Windows UI 功能(畢竟它們是 Web 應用程序)。

有多個庫用於將 HTML 轉換為 PDF。 許多 Windows/.NET 特定版本利用 IE API,因此廣泛利用 User32/GDI32。 這些 API 大部分都在沙箱中被阻止(無論計划如何),因此這些框架在沙箱中不起作用。

有一些框架沒有廣泛利用 User32/GDI32(例如 wkhtmltopdf),我們正在努力在 Basic+ 中啟用這些,就像啟用 SQL 報告一樣。

您可能需要找到一種替代方法來創建 PDF 文件或將計算移到 Azure Functions 之外。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM