Webview2 multithreading freezes/stops

235 Views Asked by At

I've been working on a fun side project. Basically I simulate two incognito browsers with Webview2. They go to persons X Instagram profile list and start liking stories of followers. I want both to execute async Javascript code at the same time. So I use multithreading. Every Webview2 browser gets a thread. The problem is that when both Webview2 instances start one instance keeps running the script-loop Method4. But it seems that the other instance runs this method for like a few seconds and freezes/stops? It's kinda weird and I don't really know what's happening. I might be overlooking something but I really can't figure it out.

private async void button1_Click(object sender, EventArgs e)
{
    TabPage tabPage = new TabPage();
    tabPage.Name = "tabPage" + (tabControl1.TabCount + 1);
    tabPage.Text = "tabPage" + (tabControl1.TabCount + 1);
    tabPage.Margin = tabControl1.TabPages[0].Margin;
    tabPage.Padding = tabControl1.TabPages[0].Padding;
    tabPage.Size = tabControl1.TabPages[0].Size;

    CustomBrowser customBrowser = new CustomBrowser(this);
    bool done = await customBrowser.InitBrowser();

    tabPage.Controls.Add(customBrowser.webView2);

    tabControl1.TabPages.Add(tabPage);

    string name = names[0];
    names.RemoveAt(0);

    Thread browserThread = new Thread(async () =>
    {
        Method4(customBrowser, name);
    });

    threads.Add(browserThread);
}

First I create a new tab with an instance of Webview2 (CustomBrowser class does all of the initializing for the Webview2 instance). And after that I create and define a thread and it to a list.

private void button2_Click(object sender, EventArgs e)
{
    foreach (Thread browserThread in threads)
    {
        browserThread.Start();
    }
}

After I created two tabs with two browsers I start all threads with the code from above. Both threads will now start executing Method4 which is:

private async void Method4(CustomBrowser customBrowser, string scrape)
{
    while (!customBrowser.BrowserStopped)
    {
        customBrowser.webView2.Invoke(new Action(async () =>
        {
            customBrowser.webView2.CoreWebView2.Navigate($"https://www.instagram.com/{scrape}/followers/");
        }));

        await Task.Delay(TimeSpan.FromSeconds(10));

        //Select follower box
        customBrowser.webView2.Invoke(new Action(async () =>
        {
            await customBrowser.webView2.ExecuteScriptAsync($"var box = document.querySelectorAll('div._aano');");
        }));  

        int index = 0;
        int lastIndex = 0;
        int increment = 500;
        while (index < 100)
        {
            customBrowser.webView2.Invoke(new Action(async () =>
            {
                await customBrowser.webView2.ExecuteScriptAsync($"box[0].scrollTop = {increment};");
                index = int.Parse(await customBrowser.webView2.ExecuteScriptAsync("document.querySelectorAll('div._aarf._aarg').length;")) - 1;
            }));

            // Get names from lastIndex to index
            if (index > lastIndex)
            {
                for (int i = lastIndex + 1; i <= index; i++)
                {
                    // Click profile picture
                    customBrowser.webView2.Invoke(new Action(async () =>
                    {
                        await customBrowser.webView2.ExecuteScriptAsync($"var profile = document.querySelectorAll('div._aarf._aarg')[{i}]; profile.scrollIntoView();");
                    }));
                    await Task.Delay(TimeSpan.FromMilliseconds(random.Next(1521, 3526)));
                    customBrowser.webView2.Invoke(new Action(async () =>
                    {
                        await customBrowser.webView2.ExecuteScriptAsync($"profile.click();");
                    }));
                    await Task.Delay(TimeSpan.FromMilliseconds(random.Next(3000, 4567)));
                    // Like story
                    customBrowser.webView2.Invoke(new Action(async () =>
                    {
                        string response = await customBrowser.webView2.ExecuteScriptAsync("var likeButton = document.querySelector('span.x1i64zmx'); if (likeButton.children[0].children[0].children[0].children[0].getAttribute('aria-label') === 'Vind ik leuk') { likeButton.children[0].click(); }");
                    }));
                    await Task.Delay(TimeSpan.FromMilliseconds(random.Next(1000, 2000)));
                    // Exit story
                    customBrowser.webView2.Invoke(new Action(async () =>
                    {
                        await customBrowser.webView2.ExecuteScriptAsync("document.querySelector('div.xjbqb8w.x1ypdohk.xw7yly9.xktsk01.x1yztbdb.x1d52u69.x10l6tqk.x13vifvy.xds687c').children[0].click();");
                    }));
                    await Task.Delay(TimeSpan.FromMilliseconds(random.Next(1521, 3526)));
                }
                lastIndex = index;
            }

            await Task.Delay(TimeSpan.FromSeconds(random.Next(1, 3)));
            increment += random.Next(500, 800);
        }

        customBrowser.BrowserStopped = true;
    }
}

This method basically like 100 Instagram stories and that's it. So that's basically all the code. One thread and one browser successfully perform Method4 and keep doing this. But the second thread only seems to be working for the first few lines of Method4 (navigating and opening follower list) and then stops working. How is this possible? I just want to simulate two independent incognito browsers and run scripts on them. Just as if I were to open two Chrome browsers.

0

There are 0 best solutions below