简体   繁体   English

Async/await, Task Parallel 对于在调试时运行 FINE 但没有运行失败的复杂进程

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

I am trying to execute a very complex operation parallely with TPL For.我正在尝试与 TPL For 并行执行一个非常复杂的操作。 It has API calling with async/await and with selenium webdriver.它使用 async/await 和 selenium webdriver 调用 API。

When I debug the application, it runs smoothly, but when I run it without debugger, it crashes shortly and following message shows.当我调试应用程序时,它运行顺利,但是当我在没有调试器的情况下运行它时,它很快就会崩溃并显示以下消息。

{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}

Here is the code, where it indicates the bitmap memory out ....这是代码,它指示位图内存输出....

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;
    }

And it is the line where its catching the error :这是它捕获错误的行:

Screenshot screenshot = ssdriver.GetScreenshot();

Here are a couple of things:这里有几件事:

  1. Don't mix Parallel.For with async and await.不要将Parallel.For与 async 和 await 混用。 It's not suited to work with the async and await pattern.它不适合使用 async 和 await 模式。
  2. Your exception is most definitely caused by running out of GDI memory because you are not disposing all your Bitmaps .您的异常绝对是由 GDI 内存不足引起的,因为您没有处理所有Bitmaps

System.OutOfMemoryException: Out of memory. System.OutOfMemoryException:内存不足。 at System.Drawing.Bitmap.Clone(Rectangle rect, PixelFormat format)在 System.Drawing.Bitmap.Clone(矩形矩形,PixelFormat 格式)

Put all your bitmaps into a using statement .将所有位图放入using 语句中

Or call Dispose immediately after you have finished with them.或者在完成Dispose后立即致电Dispose

implement try catch to find out where (possible before the line 598) out of memory, the variable may still occupied memory. 实施try catch找出内存中哪里(可能在第598行之前), 变量仍可能占用内存。 You can able to try GC.Collect(), specific generations if you know what you want to release, if solved can removed, effect performance of suspend you app in thread. 如果您知道要发布的内容,则可以尝试使用特定版本的GC.Collect(),如果可以解决,则可以将其删除,从而影响应用程序在线程中挂起的性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM