仅当从计时器调用函数时,强制转换无效



im正在尝试执行一个程序,从一个网站读取字符串并将其发送到另一个网站。第一个读取字符串的过程正常工作,还有向其他工作发送字符串的函数,但当从计时器调用此函数时出现问题。。

这是我的部分代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
using CefSharp.WinForms.Internals;
namespace CodePinger
{
public partial class Form1 : Form
{
public bool login = true;
private static System.Timers.Timer TimerCheck;
public Form1()
{
InitializeComponent();
TimerCheck = new System.Timers.Timer(5000);
TimerCheck.Elapsed += new ElapsedEventHandler(CheckEvent);
TimerCheck.AutoReset = true;
CheckForIllegalCrossThreadCalls = false;
webBrowser1.ScriptErrorsSuppressed = true;
chromiumWebBrowser1.Load("https://firstwebsite.com");
webBrowser1.Navigate("http://secondwebsite.com");
}
private async void CheckEvent(Object source, ElapsedEventArgs e)
{
if (login) { 
string script = "document.getElementById('SecondSDISP').innerText;";
JavascriptResponse jr = chromiumWebBrowser1.EvaluateScriptAsync(script).Result;
if (jr.Success)
{
if (jr.Result.ToString().Contains("01"))
{
label2.ForeColor = Color.Red;
label2.Text = jr.Result.ToString();
sendCode(jr.Result.ToString());
}
}
else
{
label2.ForeColor = Color.Black;
label2.Text = "no data";
}
label4.Text = timer.ToString();
}
}
private void button2_Click(object sender, EventArgs e)
{
TimerCheck.Enabled = true;
TimerCheck.Start();
button2.Enabled = false;
}
public void sendCode(string code)
{
string msg = "";
if (code == "1") msg = "1 coda";
else msg = code.ToString() + " code";
var textarea = webBrowser1.Document.GetElementsByTagName("textarea")[0];
textarea.InnerHtml = msg;
textarea.Focus();
var allsvg = webBrowser1.Document.GetElementsByTagName("svg");
foreach (HtmlElement svg in allsvg)
{
if (svg.GetAttribute("className").Contains("-send"))
{
svg.InvokeMember("click");
break;
}
}
}
private void button4_Click(object sender, EventArgs e)
{
sendCode("1");
}
}
}

同样在我启动计时器后,如果我点击按钮4测试功能,它就会正常工作。而不是当它从定时器调用时

错误是:

System.InvalidCastException
HResult=0x80004002
Message=Specified cast is not valid.
Source=System.Windows.Forms
StackTrace:
at System.Windows.Forms.UnsafeNativeMethods.IHTMLDocument2.GetLocation()
at System.Windows.Forms.WebBrowser.get_Document()
at CodePinger.Form1.sendCode(String code) in C:UsersFlynns82sourcereposCodePingerForm1.cs:line 105
at CodePinger.Form1.<CheckEvent>d__9.MoveNext() in C:UsersFlynns82sourcereposCodePingerForm1.cs:line 63

指示的行是:

105) var textarea = webBrowser1.Document.GetElementsByTagName("textarea")[0];
63) sendCode(jr.Result.ToString());

有人能解释一下问题出在哪里吗?

您的问题很可能是试图从非STA线程(也称为"UI线程"(访问WebBrowser

当您使用button_click处理程序时,您的代码正在STA线程上运行(默认情况下(,然而,当时间事件处理程序被调用时,它发生在不同的线程(而不是STA线程(中,因此如果您不"调用"ActiveX/组件(驻留在STA线程中(上的属性,您将在调用/访问属性时遇到问题;调用";返回STA。

我建议查看以下SO问题:STA与MTA的技术解释。

为了解决调用问题,请查看以下SO问题:自动调用所需代码模式

另一方面,浏览器会公开NavigateComplete事件,您不需要在加载页面时进行时间检查,只需将自己挂接到该事件并在导航后等待它,一旦该事件触发,DOM就会稳定。

最新更新