0

Hi I have a use case where I am supposed to use C# Web Browser inside a form and get some data from it. However as we know the C# browser runs under STA hence I have created an instance of SmartThread with single thread architecture.

On some events from an MVC app I am supposed to invoke the web browser and get the result. When the browser is instantiated at that moment I can invoke any JavaScript method, however when I wait for an event in MVC and invoke on event the SmartThread doesn't seems to invoke the webbrowser.

Here is my below code please help me.

 public class FormBrowser
 {
    public static Form1 form1 = null;
    public static SmartThreadPool smartThreadPool;

    public static void initialise()
    {
       if (smartThreadPool == null)
       {
           STPStartInfo stpStartInfo = new STPStartInfo();
           stpStartInfo.StartSuspended = true;
           stpStartInfo.ApartmentState = ApartmentState.STA;
           stpStartInfo.MaxWorkerThreads = 1;

           smartThreadPool = new SmartThreadPool(stpStartInfo);
           var ab = smartThreadPool.QueueWorkItem(new WorkItemCallback(initForm), "line");
           smartThreadPool.Start();
           //smartThreadPool.Shutdown();
       }
   }

   public static object initForm(object msg)
   {
       var id = Thread.CurrentThread.ManagedThreadId;
       form1 = new Form1();
       System.Windows.Forms.Application.Run(form1);
       return null;
   }

   public static void redraw()
   {
       var id = Thread.CurrentThread.ManagedThreadId;
       smartThreadPool.QueueWorkItem(new WorkItemCallback(rd), "line");
   }

   public static object rd(object msg)
   {
       var id = Thread.CurrentThread.ManagedThreadId;
       form1.webBrowser1.Document.InvokeScript("startDrawing");
       return null;
   }

}

On calling initialise() method SmartThread will create a thread pool and then creates a Form instance which holds a Web Browser. Next when any event occures from client say he request for a latest data I have to call method redraw() and which should internally call rd() but that never happens.

Please help me to fix this, if I am missing something let me know.

Sadanand
  • 107
  • 2
  • 11
  • 1
    You have to set ApartmentState.STA within initForm; Look at http://stackoverflow.com/questions/4269800/webbrowser-control-in-a-new-thread – volody Mar 27 '15 at 00:50
  • Yeah that's true but since I am using a smart thread pool it does set it while initializing form. Thank you. – Sadanand Mar 28 '15 at 09:01

1 Answers1

0

The below code worked for me.

public class FormBrowser
{
    public static Form1 form1 = null;
    public static SmartThreadPool smartThreadPool;
    public static SynchronizationContext ctx;
    public static string html;

    public static void initialise()
    {
        if (smartThreadPool == null)
        {
            STPStartInfo stpStartInfo = new STPStartInfo();
            stpStartInfo.StartSuspended = false;
            stpStartInfo.ApartmentState = ApartmentState.STA;
            stpStartInfo.MaxWorkerThreads = 1;

            smartThreadPool = new SmartThreadPool(stpStartInfo);
            var ab = smartThreadPool.QueueWorkItem(new WorkItemCallback(initForm), "line");
            smartThreadPool.Start();
            //smartThreadPool.Shutdown();
        }
    }

    public static object initForm(object msg)
    {
        var id = Thread.CurrentThread.ManagedThreadId;
        form1 = new Form1();
        ctx = WindowsFormsSynchronizationContext.Current;
        System.Windows.Forms.Application.Run(form1);            
        return null;
    }

    public static string redraw(string chartType)
    {
        ctx.Send(rd, chartType);
        return html;
    }

    public static void rd(object chartType)
    {
        var id = Thread.CurrentThread.ManagedThreadId;
        html = (string)form1.webBrowser1.Document.InvokeScript("drawChart", new object[] { chartType });
    }

}

If SmartThreadPool used along with the SynchronizationContext works well. However using SynchronizationContext alone or SmartThreadPool alone won't solve the issue.

Sadanand
  • 107
  • 2
  • 11