我是一个通过实例学习的 C# 程序员,水平不是很先进,这就是为什么这个问题完全难住了我,无论互联网上有多少信息。
我本质上是在创建一个程序,该程序在计时器上重复轮询网站以获取一些信息。在此过程中,将创建一个 WebBrowser 控件来导航到信息(身份验证所需的)。该程序在启动时运行这一系列事件,然后使用设置为每 10 分钟一次的 System.Timers.Timer(当然,调试时间较少)来执行相同的一系列事件,但当我的 Timer.Elapsed 事件触发该过程时,我得到A:
线程状态异常描述为ActiveX 控件“8856f961-340a-11d0-a96b-00c04fd705a2”无法实例化,因为当前线程不在单线程单元中。
这是我的程序的精简版本。
private void Form1_Load(object sender, EventArgs e)
{
GetDataFromWebBrowser();
Set_Auto_Refresh_Timer();
}
private void Set_Auto_Refresh_Timer()
{
System.Timers.Timer TimerRefresh = new System.Timers.Timer(10000);
TimerRefresh.Elapsed += new System.Timers.ElapsedEventHandler(TimerRefresh_Elapsed);
TimerRefresh.AutoReset = true;
TimerRefresh.Start();
}
private void TimerRefresh_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
GetDataFromWebBrowser();
}
private void GetDataFromWebBrowser()
{
WebBrowser wb = new WebBrowser(); <--This is where the error is thrown.
...get web data...
}
我想我已经有足够的代码来描绘这幅画了。正如您所看到的,当它开始创建另一个 WebBrowser 时,它会抛出错误。
我真的很困惑,而且我才刚刚开始了解 Threading 的表面,这可能就是我如此困惑的原因。
//我的解决方案/
我最终将 WebBrowser 创建移出了该方法,并使其静态化以仅重用 WebBrowser 控件。我还将 System.Timers.Timer 交换为 System.Threading.Timer。似乎解决了问题。
The WebBrowser 的 MSDN 文档 http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.aspx指出:
WebBrowser 类只能在设置为单线程单元 (STA) 模式的线程中使用。要使用此类,请确保您的 Main 方法是用 [STAThread] 属性标记.
另外,改变你的System.Timers.Timer
to a System.Windows.Forms.Timer
如果您想定期与 UI 控件进行交互。或者,设置同步对象 http://msdn.microsoft.com/en-us/library/system.timers.timer.synchronizingobject.aspx你的财产System.Timers.Timer
到父控件以强制计时器调用正确线程上的调用。所有 WinForms 控件只能从同一个且唯一的 UI 线程访问。
.NET 的 BCL 中有三种类型的计时器,每种类型的行为都非常不同。查看这篇 MSDN 文章进行比较:比较 .NET Framework 类库中的计时器类(网络存档) https://web.archive.org/web/20150329101415/https://msdn.microsoft.com/en-us/magazine/cc164015.aspx或这个简要比较表 https://mitch-wheat.blogspot.hr/2010/12/comparing-net-timer-classes.html.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)