logo
down
shadow

WebBrowser control in a class library


WebBrowser control in a class library

By : Alexandre Belarmino
Date : November 22 2020, 11:05 AM
To fix the issue you can do If I understood the question correctly, you need to run an instance of WebBrowser control for the lifetime of your library, and keep it alive and independent on a dedicated STA thread with its own WinForms message loop.
The code below shows how it can possibly be done, using a helper class called MessageLoopApartment. Note how the WebBrowser gets created and manipulated on a separate thread.
code :
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinForms_21772632
{
    // https://stackoverflow.com/q/21772632/1768303

    public partial class MainForm : Form
    {
        MessageLoopApartment _apartment;

        // _webBrowser is created on a separate thread,
        // with MessageLoopApartment.Run
        WebBrowser _webBrowser;

        // MainForm
        public MainForm()
        {
            InitializeComponent();

            // create an independent STA thread
            _apartment = new MessageLoopApartment();

            // create a WebBrowser on that STA thread
            _webBrowser = _apartment.Run(
                () => new WebBrowser(),
                CancellationToken.None).Result;

            this.Load += MainForm_Load;
            this.FormClosed += MainForm_FormClosed;
        }

        // navigation test
        async void MainForm_Load(object senderLoad, EventArgs eLoad)
        {
            // navigate
            var cts = new CancellationTokenSource(10000); // cancel in 10s
            var url = "http://example.com";
            var html = await _apartment.Run(async () =>
            {
                WebBrowserDocumentCompletedEventHandler handler = null;
                var navigateTcs = new TaskCompletionSource<bool>();
                handler = (s, e) =>
                    navigateTcs.TrySetResult(true);
                _webBrowser.DocumentCompleted += handler;
                try
                {
                    using (cts.Token.Register(() => navigateTcs.TrySetCanceled()))
                    {
                        _webBrowser.Navigate(url);
                        await navigateTcs.Task;
                        return _webBrowser.Document.Body.OuterHtml;
                    }
                }
                finally
                {
                    _webBrowser.DocumentCompleted -= handler;
                }
            },
            cts.Token);

            // show the HTML of the downloaded page
            MessageBox.Show(html);
        }

        void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            // destroy the WebBrowser
            _apartment.Run(
                () => _webBrowser.Dispose(),
                CancellationToken.None).Wait();

            // shut down the appartment
            _apartment.Dispose();
        }
    }

    /// <summary>MessageLoopApartment</summary>
    public class MessageLoopApartment : IDisposable
    {
        Thread _thread; // the STA thread

        TaskScheduler _taskScheduler; // the STA thread's task scheduler

        public TaskScheduler TaskScheduler { get { return _taskScheduler; } }

        /// <summary>MessageLoopApartment constructor</summary>
        public MessageLoopApartment()
        {
            var tcs = new TaskCompletionSource<TaskScheduler>();

            // start an STA thread and gets a task scheduler
            _thread = new Thread(startArg =>
            {
                EventHandler idleHandler = null;

                idleHandler = (s, e) =>
                {
                    // handle Application.Idle just once
                    Application.Idle -= idleHandler;
                    // return the task scheduler
                    tcs.SetResult(TaskScheduler.FromCurrentSynchronizationContext());
                };

                // handle Application.Idle just once
                // to make sure we're inside the message loop
                // and SynchronizationContext has been correctly installed
                Application.Idle += idleHandler;
                Application.Run();
            });

            _thread.SetApartmentState(ApartmentState.STA);
            _thread.IsBackground = true;
            _thread.Start();
            _taskScheduler = tcs.Task.Result;
        }

        /// <summary>shutdown the STA thread</summary>
        public void Dispose()
        {
            if (_taskScheduler != null)
            {
                var taskScheduler = _taskScheduler;
                _taskScheduler = null;

                // execute Application.ExitThread() on the STA thread
                Task.Factory.StartNew(
                    () => Application.ExitThread(),
                    CancellationToken.None,
                    TaskCreationOptions.None,
                    taskScheduler).Wait();

                _thread.Join();
                _thread = null;
            }
        }

        /// <summary>A wrapper around Task.Factory.StartNew</summary>
        public Task Run(Action action, CancellationToken token)
        {
            return Task.Factory.StartNew(action, token, TaskCreationOptions.None, _taskScheduler);
        }

        /// <summary>A wrapper around Task.Factory.StartNew to run lambdas with a result</summary>
        public Task<TResult> Run<TResult>(Func<TResult> action, CancellationToken token)
        {
            return Task.Factory.StartNew(action, token, TaskCreationOptions.None, _taskScheduler);
        }

        /// <summary>A wrapper around Task.Factory.StartNew to run async lambdas</summary>
        public Task Run(Func<Task> action, CancellationToken token)
        {
            return Task.Factory.StartNew(action, token, TaskCreationOptions.None, _taskScheduler).Unwrap();
        }

        /// <summary>A wrapper around Task.Factory.StartNew to run async lambdas with a result</summary>
        public Task<TResult> Run<TResult>(Func<Task<TResult>> action, CancellationToken token)
        {
            return Task.Factory.StartNew(action, token, TaskCreationOptions.None, _taskScheduler).Unwrap();
        }

    }
}


Share : facebook icon twitter icon
Using WebBrowser control in class library

Using WebBrowser control in class library


By : user3676096
Date : March 29 2020, 07:55 AM
this will help WebBrowser.Navigate( ... ) doesn't block - it returns immediately, before the request is sent. Since your thread function then exits, your whole thread ends and takes your WebBrowser control with it.
If you're just trying to download a web page, have a look at the WebClient class. It has many async methods which means you probably won't even have to create your own thread.
WebBrowser control wrapped in a custom class

WebBrowser control wrapped in a custom class


By : elapqpxsijws
Date : March 29 2020, 07:55 AM
Any of those help
I need some help on what exactly is meant by the statement "First of all I have my WebBrowser control wrapped in a custom class to add functionalities, in that class I declare this constant....."
How can I open a link from one WebBrowser control in another WebBrowser control?

How can I open a link from one WebBrowser control in another WebBrowser control?


By : Jose Carlos González
Date : March 29 2020, 07:55 AM
Assigning a webbrowser control object to another webbrowser control

Assigning a webbrowser control object to another webbrowser control


By : Sean
Date : March 29 2020, 07:55 AM
it fixes the issue I have two webbrowser control in a windows Form Application. I have navigated to a page in webbrowser control1. Now i need to assign this webbrowser1 to webbrowser2 and i need to work in these two webbrowser controls differently. , When you write this code:
code :
webbrowser2 = webbrowser1;
Web scraping using WebBrowser in a class library

Web scraping using WebBrowser in a class library


By : Raj
Date : March 29 2020, 07:55 AM
This might help you Here is what I tested in a web application and worked properly.
It uses a WebBrowser control in another thread and returns a Task containing which completes when the browser content load completely:
code :
using System;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
public class BrowserBasedWebScraper
{
    public static Task<string> LoadUrl(string url)
    {
        var tcs = new TaskCompletionSource<string>();
        Thread thread = new Thread(() => {
            try {
                Func<string> f = () => {
                    using (WebBrowser browser = new WebBrowser())
                    {
                        browser.ScriptErrorsSuppressed = true;
                        browser.Navigate(url);
                        while (browser.ReadyState != WebBrowserReadyState.Complete)
                        {
                            System.Windows.Forms.Application.DoEvents();
                        }
                        return browser.DocumentText;
                    }
                };
                tcs.SetResult(f());
            }
            catch (Exception e) {
                tcs.SetException(e);
            }
        });
        thread.SetApartmentState(ApartmentState.STA);
        thread.IsBackground = true;
        thread.Start();
        return tcs.Task;
    }
}
Related Posts Related Posts :
  • Estimating Amount Of time For Tasks Running in Parallel
  • Opening, Changing, and Saving Excel Sheets with DGV
  • Remapping of Database from one server to other TFS-2018
  • SQL Server: Dynamically create Column Names from JSON Auto Data
  • Is it possible to Install .net 4.7 version on my machine when .net 4.8 is already installed?
  • Getting server absolute path in .NET core 2.1
  • Regex to find last word (including symbols) on line
  • Adding element to a couchbase database with f# code
  • How to create "NuGet Package Management Project" for .NET Standard?
  • Blazor BaseURI http vs https issue
  • Does X590Certificate.Build use OCSP if ChainPolicy RevocationMode Online is used?
  • Error "NU3034 This package is signed but not by a trusted signer"
  • Blazor .net version compatibility issues
  • How to test async Task method
  • this project doesn't know how to run the profile docker
  • Azure Cloud Storage SDK UploadFromStreamAsync storing 0 bytes
  • What is the Relaese date for Microsoft Orleans which can support service fabric?
  • Make a string persistent in a .NET application
  • How do I configure Cosmos DB .NET 3.0 SDK to serialize with camel case?
  • Service segmentation fault in AWS EC2
  • How to avoid the compilation error with inconsistent accessibility of class and methods?
  • "Does not implement IControllerFactory.CreateController" in Visual Studio 2010
  • Tabs for a ASP.NET website
  • AccountManagement.UserPrincipal.Current takes 5 seconds
  • Will linq to sql work in an asp.net 2.0 web application?
  • .Net Regular Expression to get parenthetical text at end of <p> tags
  • The Project Location is Not Trusted error in Visual Studio
  • how to tell if a photo was taken in landscape or portrait? JPEG .NET metadata orientation
  • Winform and ValidateChildren()
  • Why need to mention "Supported by the .NET Compact Framework" for classes members?
  • Pass MSI parameters to .NET installer class
  • How to print stack trace of StackOverflowException
  • OnPropertyChange as an Alternative to Triggers in Entity Framework
  • "User Friendly" .net compatible Regex/Text matching tools?
  • Non-Ascii characters not supported by .net?
  • Linq SqlMethods.Like fails
  • To check whether the SQL server DB is working properly or not
  • What is the Difference between GC.GetTotalMemory(false) and GC.GetTotalMemory(true)
  • Which version of .NET is available for Xbox 360?
  • Validation (with custom ErrorTemplate) for a DataTemplate
  • is the threadpool shared - .net
  • WPF RichTextBox - Formatting of typed text
  • "ResizeEnd" equivalent for usercontrols
  • How work with common utils project
  • Using image resource in XAML markup?
  • How to use XML namespace prefixes without xmlns="..." everywhere? (.NET)
  • How to write an altered COM Structured Storage file to Disk?
  • Implementing auditing using Autofac if it support method interception?
  • How can a static class be resolved by the Unity Framework?
  • How to flush DNS cache in Windows Mobile programmatically?
  • how to set autoplay=true in google audio player?
  • Edit dialog, with bindings and OK/Cancel in WPF
  • What does MailMessage.IsBodyHtml do?
  • C# Class Library wont register for COM
  • Robust DateTime parser library for .NET
  • MySql BulkCopy/Insert from DataReader
  • How do I allow all users access to one route within a website with integrated auth?
  • Reading from a oracle temp table in a separate procedure than the one it was populted in
  • Recommendations for IPC between parent and child processes in .NET?
  • F# 1.9.9.9 and lapack
  • shadow
    Privacy Policy - Terms - Contact Us © festivalmusicasacra.org