Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to remove Application.DoEvents() with better solution like BackgroundWorker in multithreading
    text
    copied!<p>This is my code. I am using Application.DoEvents() for waiting that UI thread is finished.</p> <pre><code>public override void Process(Crawler crawler, PropertyBag propertyBag) { AspectF.Define. NotNull(crawler, "crawler"). NotNull(propertyBag, "propertyBag"); if (propertyBag.StatusCode != HttpStatusCode.OK) return; if (!IsHtmlContent(propertyBag.ContentType)) return; m_Logger.Verbose("CefGlue started for url {0}", propertyBag.ResponseUri.ToString()); CefGlueBrowserForm cefGlueBrowserForm = new CefGlueBrowserForm(propertyBag.ResponseUri.ToString()); cefGlueBrowserForm.Show(); while (!cefGlueBrowserForm.Done) Application.DoEvents(); string htmlSource = cefGlueBrowserForm.DocumentDomHtml; propertyBag.GetResponse = () =&gt; new MemoryStream(Encoding.UTF8.GetBytes(htmlSource)); base.Process(crawler, propertyBag); } </code></pre> <p>I am reading that <code>Application.DoEvents()</code> is evil. I am also getting sometimes stackoverflow exception. What to use instead of <code>Application.DoEvents()</code>?</p> <p>I try something with <code>BackgroundWorker</code> but nothing works</p> <p>Example:</p> <pre><code>AutoResetEvent waitHandle = new AutoResetEvent(false); BackgroundWorker bw = new BackgroundWorker(); bw.WorkerReportsProgress = true; bw.WorkerSupportsCancellation = true; bw.DoWork += (sender, e) =&gt; { if (!e.Cancel) { CefGlueBrowserForm cefGlueBrowserForm = new CefGlueBrowserForm(propertyBag.ResponseUri.ToString()); cefGlueBrowserForm.Show(); while (!cefGlueBrowserForm.Done) Application.DoEvents(); e.Result = cefGlueBrowserForm.DocumentDomHtml; cefGlueBrowserForm.Dispose(); waitHandle.Set(); } }; bw.RunWorkerCompleted += (sender, e) =&gt; { string htmlSource = e.Result.ToString(); propertyBag.GetResponse = () =&gt; new MemoryStream(Encoding.UTF8.GetBytes(htmlSource)); base.Process(crawler, propertyBag); }; bw.RunWorkerAsync(TimeSpan.FromSeconds(10)); waitHandle.WaitOne(TimeSpan.FromSeconds(20)); </code></pre> <p>What can I do?</p> <p>EDIT:</p> <p>added code how cefGlueBrowserForm.Done is set.</p> <pre><code> public partial class CefGlueBrowserForm : Form { public CefGlueBrowserForm(string url) { m_Logger = NCrawlerModule.Container.Resolve&lt;ILog&gt;(); m_url = url; InitializeComponent(); CefManager.InitializeCef(); AddWebBrowser(m_url); } private void AddWebBrowser(string startUrl) { m_textBox = new TextBox { Dock = DockStyle.Bottom, ReadOnly = true, }; m_textBox.Parent = this; Console.Box = m_textBox; Console.WriteLine("Loading URL ..."); CefGlueBrowser = new ChromiumCefWebBrowser(); CefGlueBrowser.Dock = DockStyle.Fill; CefGlueBrowser.BringToFront(); CefGlueBrowser.StartUrl = startUrl; CefGlueBrowser.Parent = this; Controls.Add(CefGlueBrowser); Console.WriteLine("URL " + startUrl + " loaded."); CefGlueBrowser.LoadEnd += Browser_LoadEnd; } private void Browser_LoadEnd(object sender, EventArgs e) { m_Logger.Verbose("Page load was ended for url {0}", m_url); MyCefStringVisitor visitor = new MyCefStringVisitor(this, m_url); ((LoadEndEventArgs)e).Frame.Browser.GetMainFrame().GetSource(visitor); } private class MyCefStringVisitor : CefStringVisitor { #region Instance Fields private CefGlueBrowserForm m_cefGlueBrowserForm; private string m_url; private ILog m_Logger; #endregion #region Constructors public MyCefStringVisitor(CefGlueBrowserForm cefGlueBrowserForm, string url) { m_Logger = NCrawlerModule.Container.Resolve&lt;ILog&gt;(); m_cefGlueBrowserForm = cefGlueBrowserForm; m_url = url.NormalizeUrl(); } #endregion #region Instance Methods protected override void Visit(string value) { string currentUrl = m_cefGlueBrowserForm.CefGlueBrowser.Browser.GetMainFrame().Url.NormalizeUrl(); if (m_url.Equals(currentUrl, StringComparison.OrdinalIgnoreCase) || currentUrl.Contains(m_url)) { m_Logger.Verbose("Getting html source for url {0} and closing Event", m_url); m_cefGlueBrowserForm.DocumentDomHtml = value; m_cefGlueBrowserForm.Done = true; m_cefGlueBrowserForm.CefGlueBrowser.LoadEnd -= m_cefGlueBrowserForm.Browser_LoadEnd; } } #endregion } #endregion } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload