0

from the class I am calling thread with

using (GeckoBrowserForm geckoBrowserForm = new GeckoBrowserForm(XulRunnerPath, propertyBag.ResponseUri.ToString()))
{
    geckoBrowserForm.show();
}

that execute UI form OnLoad(EventArgs e)

protected override void OnLoad(EventArgs e)
{
    GeckoWebBrowser m_GeckoWebBrowser = new GeckoWebBrowser();
    m_GeckoWebBrowser.Invoke(new Action(() => {
                m_GeckoWebBrowser.Parent = this;
                m_GeckoWebBrowser.Dock = DockStyle.Fill;
                m_GeckoWebBrowser.DocumentCompleted += (s, ee) =>
                {    
                    GeckoHtmlElement element = null;
                    var geckoDomElement = m_GeckoWebBrowser.Document.DocumentElement;
                    if (geckoDomElement != null && geckoDomElement is GeckoHtmlElement)
                    {
                        element = (GeckoHtmlElement)geckoDomElement;
                        DocumentDomHtml = element.InnerHtml;
                    }



      if (m_Url.Equals(m_GeckoWebBrowser.Document.Url.ToString(), StringComparison.OrdinalIgnoreCase))
                    {
                        Done = true;
                        //m_GeckoWebBrowser.Navigate("about:blank");
                        //m_GeckoWebBrowser.Document.Cookie = "";
                        //m_GeckoWebBrowser.Stop();
                    }
                };

                m_GeckoWebBrowser.Navigate(m_Url);
            }));
}

but problem is that code inside Invoke is never executed. Why? How can i execute code inside invoke?

Problem is that GeckoBrowser is a Windows Forms Control. A Control's properties and methods may be called only from the thread on which the Control was created. To do anything with a Control from another thread, you need to use the Invoke or BeginInvoke method, e.g. but how?

Ondrej Janacek
  • 12,486
  • 14
  • 59
  • 93
senzacionale
  • 20,448
  • 67
  • 204
  • 316

1 Answers1

1

OnLoad is called on the UI-thread, therefore invoking is not necessary. Besides that, you could also call these initialization steps in the constructor of the class.

Update: To create it with a SynchronizationContext:

void ThreadFunc(object args)
{
    ...
    var syncContext = (SynchronizationContext) args;
    syncContext.Send(new SendOrPostCallback(_ => {
        using (GeckoBrowserForm geckoBrowserForm = new GeckoBrowserForm(XulRunnerPath, propertyBag.ResponseUri.ToString()))
        {
            geckoBrowserForm.ShowDialog();
        }),
        null);
    ...
}
code-factory
  • 249
  • 1
  • 4
  • 11
  • then I get GeckoFx can only be called from the same thread on which it was initialized – senzacionale Dec 14 '13 at 18:10
  • 1
    Ok, now I think I understand your problem: the form is created from a worker thread, therefore it is not attached to the UI thread. Try to create the form instead in the UI thread (for example, with a SynchronizationContext-object passed to your thread). – code-factory Dec 14 '13 at 18:13
  • 1
    See updated answer above. It is important that you pass the SynchronizationContext to the thread-function. Every threading-API (for example, ThreadPool-class, TPL, Thread-class, ...) gives you the possibility to pass an arbitrary object to the thread function. – code-factory Dec 15 '13 at 08:22
  • Thank you but i get "system.action is not assignable to parameter type System.Threading.SendOrPostCallback" – senzacionale Dec 15 '13 at 09:02