0

可能重复:
新线程中的 WebBrowser 控件

我正在尝试自动单击网页上的某些元素,然后在每次单击时生成一个新的 IE 窗口。

下面的代码读取一个 DataTable,其中一列包含我需要单击的元素 ID。然后循环表格并单击 Webbrowser 中所需的元素webNav.webBrowser1

该代码第一次运行时运行良好,但此后不再有点击事件。如果我逐步使用断点,那么我可以看到代码运行良好,没有问题。看起来好像它正在安排永远不会触发的操作。

这是我第一次尝试使用线程,所以我可能会做一些根本错误的事情。

目前我有点难过问题是什么?

[STAThread]
private void ClickOptions()
{
    DataTable _dataTableTestClone = new DataTable();
    _dataTableTestClone = _dataTableTest;

    if (_dataTableTest != null)
    {
        var thread = new Thread(() =>
        {
            foreach (DataRow row in _dataTableTestClone.Rows)
            {
                string getclickID = row["ID"].ToString();

                webNav.webBrowser1.Invoke(new Action(() =>
                {
                    HtmlElement lit = webNav.webBrowser1.Document.GetElementById(getclickID);
                    if (lit != null)
                    {
                        lit.InvokeMember("click");
                    }
                }));

                Thread.Sleep(2000);
            }
        });
        thread.SetApartmentState(ApartmentState.STA);
        thread.IsBackground = true;
        thread.Start();
    }
}
4

1 回答 1

2

为什么将线程单元状态设置为 STA?我不认为它有任何目的。只有用于创建控件或与某些 COM 对象交互的线程需要是 STA(这不是您从那里开始的线程,因为 webBrowser1 上的 Invoke() 调用会将您的操作编组到 UI 线程)。

您可以尝试使用 try/catch 将代码包装在 Invoke 内部,并在 catch 块内部添加断点以查看是否弹出任何异常,因为多线程场景中的异常有时会根据具体情况表现得有些滑稽您的应用程序的其余部分已设置。我敢打赌你会得到一个被某个地方吞下的异常。

编辑:如果您的线程的唯一目的是在调用的操作之间有 2 秒的延迟,我会使用 System.Windows.Forms.Timer 代替:

http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx

于 2012-10-16T18:53:31.390 回答