How might I create and use a WebBrowser control on a worker thread?

c#, multithreading, webbrowser-control

Solution

Try setting the ApartmentState of the thread hosting the browser control:

var thread = new Thread(objThreadStart);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();

Problem

I am creating an application that does screen shots of websites using the following method http://pietschsoft.com/post/2008/07/C-Generate-WebPage-Thumbmail-Screenshot-Image.aspx I tried to make the application multithreaded but I have run into the following error: [ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment.] Any suggestions how to fix this issue? My code is basically as follows: ``` List<string> lststrWebSites = new List<string>(); lststrWebSites.Add("http://stackoverflow.com"); lststrWebSites.Add("http://www.cnn.com"); foreach (string strWebSite in lststrWebSites) { System.Threading.ThreadStart objThreadStart = delegate { Bitmap bmpScreen = GenerateScreenshot(strWebSite, -1, -1); bmpScreen.Save(@"C:\" + strWebSite + ".png", System.Drawing.Imaging.ImageFormat.Png); }; new System.Threading.Thread(objThreadStart).Start(); } ``` The GenerateScreenShot() function implementation is copied from the above URL: ``` public Bitmap GenerateScreenshot(string url) { // This method gets a screenshot of the webpage // rendered at its full size (height and width) return GenerateScreenshot(url, -1, -1); } public Bitmap GenerateScreenshot(string url, int width, int height) { // Load the webpage into a WebBrowser control WebBrowser wb = new WebBrowser(); wb.ScrollBarsEnabled = false; wb.ScriptErrorsSuppressed = true; wb.Navigate(url); while (wb.ReadyState != WebBrowserReadyState.Complete) { Application.DoEvents(); } // Set the size of the WebBrowser control wb.Width = width; wb.Height = height; if (width == -1) { // Take Screenshot of the web pages full width wb.Width = wb.Document.Body.ScrollRectangle.Width; } if (height == -1) { // Take Screenshot of the web pages full height wb.Height = wb.Document.Body.ScrollRectangle.Height; } // Get a Bitmap representation of the webpage as it's rendered in // the WebBrowser control Bitmap bitmap = new Bitmap(wb.Width, wb.Height); wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height)); wb.Dispose(); return bitmap; } ```

Original source