0

I am able to run WebBrowser in single threaded Env

But I am unable to run it in multithreaded env its throwing access violation error.

I am trying to run mutliple webbrowser instances and then taking screenshots.

Please have a look at the attached code.`

public class Image
{
    public int id { get; set; }
    public string url { get; set; }

}

internal class RenderMultipleImages
{

    //Sample Urls which contains Ajax Calls
    private static readonly List<Image> images = new List<Image>()
    {
       new Image(){id=1, url="www.abc1.com"},
       new Image() {id=2,url= "www.abc2.com"},
       new Image() {id=3,url= "www.abc3.com"},
       new Image() {id=4,url= "www.abc4.com"},
       new Image() {id=5, url="www.abc5.com"},
       new Image() {id=6,url= "www.abc6.com"}
    };

    private static int _imageWidth = 1200;
    private static int _imageHeight = 800;


    public static void Render()
    {
        var startTime = DateTime.UtcNow;

        var tasks = new List<Task>();
        for (var i = 0; i < images.Count; i++)
        {
            var i1 = i;
            var task = Task.Factory.StartNew(() => InvokeGenerateImage(images[i1].id, images[i1].url));
            tasks.Add(task);

        }
        Task.WaitAll(tasks.ToArray());
        Console.WriteLine("Time taken to finish: {0}", (DateTime.UtcNow - startTime).TotalSeconds);
    }

    private static void InvokeGenerateImage(int instanceNumber, string url)
    {
        var thread = new Thread(() => GenerateImage(instanceNumber, url));
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
        thread.Join();
    }
    //[STAThread]
    private static void GenerateImage(int instanceNumber, string url)
    {
        Console.WriteLine("Started instance number: {0}", instanceNumber);

        var browser = new WebBrowser
        {
            ScrollBarsEnabled = false,
            ScriptErrorsSuppressed = true,
            Width = _imageWidth,
            Height = _imageHeight
        };
        browser.Navigate(url);

        while (browser.ReadyState != WebBrowserReadyState.Complete)
        {
            Application.DoEvents();
        }

        //As the url contains ajax calls am checking for the element id which tells us document loaded 
        while (browser.Document != null && browser.Document.GetElementById("chart-1") == null)
        {
            Application.DoEvents();
        }

        //Then screenshot
        saveScreeshot(browser, instanceNumber);

        browser.Dispose();

        Console.WriteLine("Finished instance number: {0}", instanceNumber);
    }

    static void saveScreeshot(WebBrowser webb,int instance)
    {
        Bitmap bitmap = new Bitmap(1024, 768);
        Rectangle bitmapRect = new Rectangle(0, 0, 1024, 768);
        webb.Size = new Size(1024, 768);
        webb.DrawToBitmap(bitmap, bitmapRect);
        var name = instance + ".png";
        bitmap.Save(name, ImageFormat.Png);
        bitmap.Dispose();
    }


}

}`

Arun
  • 205
  • 2
  • 4
  • You tried `var thread ...; thread.IsBackground = true` already? and i think you might confuse Task and Thread ... – Essigwurst Sep 02 '16 at 09:14
  • @Essigwurst yaa tried But still exception coming Attempted to read or write protected memory. This is often an indication that other memory is corrupt. – Arun Sep 02 '16 at 09:18
  • @Surya, check [this](http://stackoverflow.com/a/22262976/1768303). – noseratio Sep 02 '16 at 09:46
  • @Noseratio Thank you. As mentioned I need to run multiple webbrowser instances parallel. is there anyway i can use your code with parallel.foreach ?? – Arun Sep 02 '16 at 12:45
  • @Surya, did you actually read it? if so, you might have noticed the "Adding a pool of WebBrowser objects" link there which does exactly that. Besides, using `parallell.foreach` is not really a good idea, as discussed there in the comments. – noseratio Sep 02 '16 at 12:53
  • 1
    @Noseratio Sorry I have missed that part. Thank you so much for your help – Arun Sep 02 '16 at 15:20
  • Webbrowser is an STA component. Paralleling does not make sense as all calls are still serialized. – Sheng Jiang 蒋晟 Sep 03 '16 at 00:57
  • The given demo perfectly working in Console application. We have an api which has to take screenshots of given webpages, I tried to run console.exe in n service bus through Process.Start() and its not seems to be working any Idea whats gone wrong?? – Arun Sep 08 '16 at 10:06
  • @Noseratio Any thoughts on this? – Arun Sep 08 '16 at 10:59
  • @Surya, not sure. Maybe [this](http://stackoverflow.com/q/897568/1768303)? – noseratio Sep 08 '16 at 12:55

0 Answers0