Reputation: 33
I need to capture thumbnails of apsx forms which I am able to do with the below code.But the problem is I have around 12000 forms to be captured and my code runs for about 2 minutes and captures like 1500 thumbnails and stops executing without giving any Exception or Error. Please help.
private Bitmap GenerateThumbnail(string Url, int BrowserWidth, int BrowserHeight, int ThumbnailWidth, int ThumbnailHeight)
{
this.Url = Url;
this.BrowserWidth = BrowserWidth;
this.BrowserHeight = BrowserHeight;
this.Height = ThumbnailHeight;
this.Width = ThumbnailWidth;
Thread thread = new Thread(new ThreadStart(GenerateThumbnailInteral));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
return ThumbnailImage;
}
private void GenerateThumbnailInteral()
{
System.Windows.Forms.WebBrowser webBrowser = new System.Windows.Forms.WebBrowser();
webBrowser.ScrollBarsEnabled = false;
webBrowser.Navigate(this.Url);
webBrowser.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
while (webBrowser.ReadyState != System.Windows.Forms.WebBrowserReadyState.Complete)
{
System.Windows.Forms.Application.DoEvents();
}
webBrowser.Dispose();
}
private void WebBrowser_DocumentCompleted(object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs e)
{
System.Windows.Forms.WebBrowser webBrowser = (System.Windows.Forms.WebBrowser)sender;
webBrowser.ClientSize = new Size(this.BrowserWidth, this.BrowserHeight);
webBrowser.ScrollBarsEnabled = false;
this.ThumbnailImage = new Bitmap(webBrowser.Bounds.Width, webBrowser.Bounds.Height);
webBrowser.BringToFront();
webBrowser.DrawToBitmap(ThumbnailImage, webBrowser.Bounds);
this.ThumbnailImage = (Bitmap)ThumbnailImage.GetThumbnailImage(Width, Height, null, IntPtr.Zero);
this.ThumbnailImageSmall = (Bitmap)ThumbnailImage.GetThumbnailImage(200, 200, null, IntPtr.Zero);
}
private void SaveImageThumbnail(List<FormClass> objFormClass)
{
try
{
string url = string.Empty;
string folderName = string.Empty;
foreach (FormClass form in objFormClass)//12000 forms
{
InternetSetCookie(url, authCookieName, authCookieValue);
InternetSetCookie(url, "RP_si", rsiCookieValue);
filepath = "D:\\Previews\\";
folderName = form.FormId.ToString();
url = string.Format("http://localhost/CRM/Sockets/{0}", form.FileName);
if (!Directory.Exists(filepath + folderName))
{
Directory.CreateDirectory(filepath + folderName);
}
Bitmap image = GenerateThumbnail(url, 1024, 700, 600, 500);
image.Save(string.Format("{0}{1}/{2}-medium.jpg", filepath, folderName, form.FormId), System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
catch (Exception exp)
{
Logger.Error("Unhandled Exception", exp);
}
}
public bool SaveThumbnails(string filePath, string authCookieName, string authCookieValue, string rpsiCookieValue)
{
this.authCookieName = authCookieName;
this.authCookieValue = authCookieValue;
this.rsiCookieValue = rpsiCookieValue;
this.filepath = filePath;
try
{
List<FormClass> globalForms = formRepo.GetForms().ToList();//Returns 12000 forms from database
SaveImageThumbnail(globalForms.ToList());
return true;
}
catch (Exception ex)
{
Logger.Error(ex.Message, ex);
}
}
From Controller I call this method like this.
public void SaveThumbnailImage(string Guid)
{
try
{
var formsService = SvcUnityContainer.DefaultContainer.WithStandardMappings().Resolve<IFormsService>();
new Thread(() => formsService.SaveThumbnails("D:\\Previews\\", FormsAuthentication.FormsCookieName, HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName].Value, HttpContext.Request.Cookies["RP_si"].Value)).Start();
}
catch (Exception exp)
{
Logger.Error(exp.Message, exp);
}
}
Upvotes: 3
Views: 189
Reputation: 50672
600 x 500 x 1500 = 450000000 pixels, that is 1350 megabytes of pixel data (3 bytes per pixel).
The process is running out of memory.
Disposing the Bitmaps is vital. You will run into a delay once the all memory is claimed and the Garbage Collector kicks in to free it but the process should continue after a bit.
Change this:
Bitmap image = GenerateThumbnail(url, 1024, 700, 600, 500);
image.Save(
string.Format("{0}{1}/{2}-medium.jpg", filepath, folderName, form.FormId),
System.Drawing.Imaging.ImageFormat.Jpeg);
to this:
using(Bitmap image = GenerateThumbnail(url, 1024, 700, 600, 500))
{
image.Save(
string.Format("{0}{1}/{2}-medium.jpg", filepath, folderName, form.FormId),
System.Drawing.Imaging.ImageFormat.Jpeg);
}
On a side note: you might want to consider re-using the same web browser, that might help in speeding up the program. Instantiating and disposing the web browser 1500 times in a row might be a waste of time if you can (cleanly) re-use it.
Upvotes: 1