我正在尝试自动点击网页上的某个元素,然后在每次点击时生成一个新的IE窗口。
下面的代码读取一个DataTable,其中一列包含我需要单击的元素ID。然后它循环表并在Web浏览器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();
}
}
答案 0 :(得分: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