Async/await,任务并行对于复杂的过程 运行在调试时 FINE 开启但未能 运行 没有
Async/await, Task Parallel For complex process running FINE on while debugging but failed to run without
我正在尝试与 TPL For 并行执行一个非常复杂的操作。它有 API 调用 async/await 和 selenium webdriver。
当我调试应用程序时,它 运行 很顺利,但是当我 运行 它没有调试器时,它很快就会崩溃并显示以下消息。
{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();
这里有一些事情:
- 不要将
Parallel.For
与 async 和 await 混合使用。它不适合使用异步和等待模式。
- 您的异常肯定是由 运行 GDI 内存不足引起的,因为您没有处理所有
Bitmaps
。
System.OutOfMemoryException: Out of memory. at
System.Drawing.Bitmap.Clone(Rectangle rect, PixelFormat format)
将所有位图放入 using statement。
或者在您处理完它们后立即致电 Dispose
。
我正在尝试与 TPL For 并行执行一个非常复杂的操作。它有 API 调用 async/await 和 selenium webdriver。
当我调试应用程序时,它 运行 很顺利,但是当我 运行 它没有调试器时,它很快就会崩溃并显示以下消息。
{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();
这里有一些事情:
- 不要将
Parallel.For
与 async 和 await 混合使用。它不适合使用异步和等待模式。 - 您的异常肯定是由 运行 GDI 内存不足引起的,因为您没有处理所有
Bitmaps
。
System.OutOfMemoryException: Out of memory. at System.Drawing.Bitmap.Clone(Rectangle rect, PixelFormat format)
将所有位图放入 using statement。
或者在您处理完它们后立即致电 Dispose
。