Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在不同线程上访问WebBrowser_C#_Multithreading_Browser - Fatal编程技术网

C# 在不同线程上访问WebBrowser

C# 在不同线程上访问WebBrowser,c#,multithreading,browser,C#,Multithreading,Browser,我想从不同的线程访问静态WebBrowser 以下是我的示例代码: public partial class MainFrame : Form { public static WebBrowser webBrowser = new WebBrowser(); public MainFrame() { InitializeComponent(); } } class Job { public void Process()

我想从不同的线程访问静态WebBrowser

以下是我的示例代码:

public partial class MainFrame : Form
{
    public static WebBrowser webBrowser = new WebBrowser();

     public MainFrame()
     {
         InitializeComponent();
     }
}

class Job
{
    public void Process()
    {
        MainFrame.webBrowser.Navigate("http://www.google.com");
        while (MainFrame.webBrowser.ReadyState != WebBrowserReadyState.Complete)
        {
            Thread.Sleep(1000);
            Application.DoEvents();
        }
    }
}
为了简单起见,假设我有两个线程。线程1调用Process()函数并等待它完成,因此在此阶段webBrowser应该处于Complete
WebBrowserReadyState
模式

线程1完成10秒后,线程2调用
Process()
函数。此时,如果我调试代码并在
Process()
函数的第一行设置断点,然后观察
MainFrame.webBrowser
变量,我会看到:

换句话说,它不知何故是不可接近的。有人知道这个问题的解决办法吗

附加信息:线程1启动后10秒 完成后,如果我再次调用线程1,那么一切看起来都很好


不能从未创建控件的线程直接调用WebBrowser控件的方法或属性。您需要将此类调用代理到控件的父线程中。一种方法是使用,但它是异步的

如果您真的需要同步进行,您可以使用,如下所示:

public partial class MainFrame : Form
{
    public static WebBrowser webBrowser = new WebBrowser();

    public static System.Threading.SynchronizationContext mainThreadContext = System.Threading.SynchronizationContext.Current;


    public MainFrame()
    {
        InitializeComponent();
    }
}

class Job
{
    public void Process()
    {
        mainThreadContext.Send(delegate 
        {
            MainFrame.webBrowser.Navigate("http://www.google.com");
        }, null);

        bool ready = false;
        while (!ready)
        {
            mainThreadContext.Send(delegate 
            {
                ready = MainFrame.webBrowser.ReadyState != WebBrowserReadyState.Complete;
            }, null);
            Thread.Sleep(1000);
            // if you don't have any UI on this thread, DoEvent is redundant
            Application.DoEvents(); 
        }
    }
}

无论如何,上面的代码在我看来不是一个好的设计。你想达到什么目标?也许有更好的办法。也许,您可以只使用event?

WebBrowser是一个单线程COM对象。从工作线程检查它并不能达到您希望的效果,它需要拥有浏览器的线程运行。不是,它被调试器冻结了。这也意味着使用线程是毫无意义的。