簡體   English   中英

Async/await, Task Parallel 對於在調試時運行 FINE 但沒有運行失敗的復雜進程

[英]Async/await, Task Parallel For complex process running FINE on while debugging but failed to run without

我正在嘗試與 TPL For 並行執行一個非常復雜的操作。 它使用 async/await 和 selenium webdriver 調用 API。

當我調試應用程序時,它運行順利,但是當我在沒有調試器的情況下運行它時,它很快就會崩潰並顯示以下消息。

{System.OutOfMemoryException: Out of memory.
   at System.Drawing.Bitmap.Clone(Rectangle rect, PixelFormat format)
   at Browser_Automation.Parser.CropImage(Bitmap source, Rectangle section) in E:\Work\XXXXX\XXXXX\XXXXX Automation\JSON\SuiteParser.cs:line 598
   at XXXXX.Parser.GetCaptchaById(IWebDriver driver, String id) in E:\Work\XXXXX\XXXXX\XXXXXAutomation\JSON\SuiteParser.cs:line 577
   at Browser_Automation.Parser.<GetFirstCaptchaUrl>d__23.MoveNext() in E:\Work\XXXXX\XXXXX\XXXXXAutomation\JSON\SuiteParser.cs:line 526
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Browser_Automation.Parser.<_Execute>d__27.MoveNext() in E:\Work\SupportKing\VisaBot\Browser Automation\JSON\SuiteParser.cs:line 646}

這是代碼,它指示位圖內存輸出....

private string GetCaptchaById(IWebDriver driver, string id)
    {
        //Getting the image, which is in this case has a url as source.
        var captcha_image = driver.FindElement(By.Id(id));
        string resultBase64 = "";
        if (captcha_image != null)
        {

            try
            {
                //Deleting previous screenshot images from the folder
                System.IO.DirectoryInfo di = new DirectoryInfo(App.Directory.FullName + "\\ScreenshotImages");
                foreach (FileInfo file in di.GetFiles())
                {
                    file.Delete();
                }
            }
            catch (Exception ex)
            {
            }


            var path1 = App.Directory.FullName + "\\ScreenshotImages\\" + Guid.NewGuid().ToString() + ".png";

            //Creating screenshot of the full web page and saving it to the path
            ITakesScreenshot ssdriver = driver as ITakesScreenshot;
            Screenshot screenshot = ssdriver.GetScreenshot();
            Screenshot tempImage = screenshot;
            tempImage.SaveAsFile(path1, ScreenshotImageFormat.Png);

            //Creating a rectangle of same size as the captcha
            Point point = captcha_image.Location;
            point.X = point.X;
            point.Y = point.Y;
            int width = captcha_image.Size.Width;
            int height = captcha_image.Size.Height;
            Rectangle section = new Rectangle(point, new System.Drawing.Size(width, height));

            //Loding the full page image from the path
            Bitmap fullImg = new Bitmap(path1);

            //creating a new image as the same width height of the captcha
            Bitmap source = new System.Drawing.Bitmap(width, height);

            //This is the final captcha image. We are croping the captcha image from the full image with location(X,Y) and size(W,H)
            Bitmap final_image = CropImage(fullImg, section);

           resultBase64 = ConvertBitmapToBase64(final_image);
            //final_image.Save(@"E:\\out.jpg");
        }

        return resultBase64;
    }

這是它捕獲錯誤的行:

Screenshot screenshot = ssdriver.GetScreenshot();

這里有幾件事:

  1. 不要將Parallel.For與 async 和 await 混用。 它不適合使用 async 和 await 模式。
  2. 您的異常絕對是由 GDI 內存不足引起的,因為您沒有處理所有Bitmaps

System.OutOfMemoryException:內存不足。 在 System.Drawing.Bitmap.Clone(矩形矩形,PixelFormat 格式)

將所有位圖放入using 語句中

或者在完成Dispose后立即致電Dispose

實施try catch找出內存中哪里(可能在第598行之前), 變量仍可能占用內存。 如果您知道要發布的內容,則可以嘗試使用特定版本的GC.Collect(),如果可以解決,則可以將其刪除,從而影響應用程序在線程中掛起的性能。

暫無
暫無

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

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