1

编辑:这个问题的一部分已经在其他地方得到了回答,但我觉得这个线程提供了更多信息,可能很容易知道

标题几乎说明了一切,但这里有更多信息:

我有一个函数,它使用全局 WebbBowser 对象的 HTMLdocument 来搜索特定对象(即文本框)。当找到对象时,它会被赋予一个值。

该函数如下所示:

    public static void Set_Elements_Input(string element_name, string value)
    {
        HtmlElementCollection hec = _wb.Document.GetElementsByTagName("input");

        foreach (HtmlElement he in hec)
        {
            if (he.GetAttribute("name") == element_name)
            {
                he.SetAttribute("value", value);
            }
        }
    }

由于某些情况,我无法在我的编程环境中进行调试。所以我必须运行生成的 .exe 来查看它是否有效。它没有。

我的程序崩溃并且崩溃报告指出崩溃是由 InvalidcastException 引起的。

在 MessageBox.Show() 方法的帮助下,我设法找到了一切顺利的地方:

       MessageBox.Show("I got here!");
       HtmlElementCollection hec = _wb.Document.GetElementsByTagName("input");
       MessageBox.Show("I didn't get here!");

这让我觉得很奇怪,因为我看不出这怎么会引发 InvalidCastException。我知道 foreach 可以使用强制转换,但我的程序似乎永远不会到达该代码。那,而且 HTMLElementCollection 是 HTMLElements 的集合,所以我看不出这将如何处理 InvalidCastException。也许当集合为空时,但我认为有一个不同的例外。

比我想象的要多,也许是因为我正在使用线程并且我必须使用调用。但是http://msdn.microsoft.com/en-us/library/system.windows.forms.htmlelementcollection.aspx说 HtmlElementCollections 是线程安全的(或者与它无关?)。那,并且函数是静态的,所以我什至不确定我是否可以调用。

长话短说,到底是怎么回事?我该如何解决?

4

4 回答 4

1

也许在这里找到了答案Threading and webbrowser control

_wb.Invoke(new Action(() => {

    HtmlElementCollection hec = _wb.Document.GetElementsByTagName("input");

    foreach (HtmlElement he in hec)
    {
        if (he.GetAttribute("name") == element_name)
        {
            he.SetAttribute("value", value);
        }
    }
 }
于 2013-04-24T07:19:52.010 回答
0

我认为您正在尝试将 HTMLElement 转换为集合。只是一个猜测。你不妨试试

HtmlElement hec = _wb.Document.GetElementsByTagName("input");
于 2013-04-24T07:21:25.920 回答
0

我认为你的foreach原因。foreach不得不投去工作IEnumerable。如果它是由集合实现的,则使用var inforeach将从中获取类型。IEnumerable<T>

于 2013-04-24T07:21:34.763 回答
0

好的,所以我查看了答案,并设法解决了问题。由于某种原因,线程是问题所在。尽管 HTMLElementsCollection 是线程安全的,但 WebBrowser 类不是,所以我不得不调用它:

    public static void Set_Elements_Input(string element_name, string value)
    {
        if (_wb.InvokeRequired)
        {
            _wb.Invoke(new Action(() => { Set_Elements_Input(element_name, value); }));
        }
        else
        {
            HtmlElementCollection hec = _wb.Document.GetElementsByTagName("input");

            foreach (HtmlElement he in hec)
            {
                if (he.GetAttribute("name") == element_name)
                {
                    he.SetAttribute("value", value);
                }
            }
        }
    }

但是有人知道为什么原始代码会抛出 InvalidCastException 吗?

于 2013-04-24T07:30:39.813 回答