c# - 定时器和线程的问题

标签 c# multithreading timer

我是一个通过示例学习的 C# 编码人员,但不是很先进,这就是为什么无论 Internet 上的信息量如何,这个问题都完全困扰着我。

我实际上是在创建一个程序,该程序在计时器上反复轮询网站以获取一些信息。在此过程中,将创建一个 WebBrowser 控件以导航到信息(需要进行身份验证)。该程序在启动时运行这一系列事件,然后使用 System.Timers.Timer 设置为每 10 分钟(当然调试时间更少)来执行相同系列的事件,但是当我的 Timer.Elapsed 事件触发该过程时,我得到一个:

ThreadStateException,描述为 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。似乎解决了问题。

最佳答案

MSDN documentation for WebBrowser指出:

The WebBrowser class can only be used in threads set to single thread apartment (STA) mode. To use this class, ensure that your Main method is marked with the [STAThread] attribute.

此外,如果您想定期与 UI 控件交互,请将 System.Timers.Timer 更改为 System.Windows.Forms.Timer。或者,设置 SynchronizingObject您的 System.Timers.Timer 属性到父控件,以强制您的计时器在正确的线程上调用调用。所有 WinForms 控件只能从同一个且唯一的 UI 线程访问。

.NET 的 BCL 中有三种类型的计时器,每种计时器的作用都非常不同。查看这篇 MSDN 文章进行比较:Comparing the Timer Classes in the .NET Framework Class Library (web archive)或者这个 brief comparison table .

关于c# - 定时器和线程的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9076041/

相关文章:

c# - 通用 KeyValuePair 和类型推断

java - Java跨线程函数调用

c# - 数千个并发数据包,ThreadPool vs BeginRead?

java - BlackBerry项目中Timer的使用

c - 如何从文件描述符中获取 read() 的最小字节数?

c++ - 如何在多线程中安全地使用 boost deadline timer?

C# 从 BindingSource 刷新文本框

c# - 如何检测窗口在现代多显示器系统上是否可见

c# - 发送短信的 AT 命令之间的时间延迟

java - java中线程的顺序执行