获取InvalidCast操作异常和跨线程操作无效 [英] Getting InvalidCast operation Exception and Cross-thread operation not valid

查看:108
本文介绍了获取InvalidCast操作异常和跨线程操作无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将计时器设置为1分钟。当我调用onTimeEvent时,我在kbd.hide上获取异常,并且同时获取元素。可以帮助我解决任何问题。代码中有异常作为注释。提前致谢

I have a timer set to 1 minute. When I call onTimeEvent I get exception at kbd.hide and also while fetching elements.Can any one please help me to fix it.Exceptions are there in the code as comments. Thanks in advance

private static System.Timers.Timer aTimer,btimer;
aTimer = new System.Timers.Timer();
            aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            aTimer.Interval = 1000 * 60 * 1;
            aTimer.Enabled = true;
            GC.KeepAlive(aTimer);




void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
            try
            {
                kbd.Hide();//Cross-thread operation not valid: Control 'KeyBoardForm' accessed from a thread other than the thread it was created on
            }
            catch (InvalidOperationException ioe)
            {
               Console.WriteLine( ioe.Message) ;
            }
            showandhidekbd = true;
            
                HtmlElementCollection elements = this.wbrowser1.Document.Body.GetElementsByTagName("input");//Invalid cast operation

                for (var i = 0; i < elements.Count; i++)
                {
                    elements[i].InnerText = "";
                }
            }

推荐答案

System.Timers.Timer将在任何感觉到的线程上触发它的事件。更新GUI时,必须首先由创建控件的线程完成。这就是你得到这个例外的原因



我不确定你是在WinForms还是WPF,但两者都有用于此目的的计时器。尝试其中之一。 System.Windows.Forms.Timer(可能)或System.Windows.Threading.DispatcherTimer。
System.Timers.Timer will fire its event on any thread it feels like. When you update the GUI, it has to be done by the thread which created the control in the first place. This is why you are getting that exception

I'm not sure whether your in WinForms or WPF, but both have timers for this purpose. Try one of those. System.Windows.Forms.Timer (maybe) or System.Windows.Threading.DispatcherTimer.


这一切都按预期进行。让我们来看看。这种类型的计时器在一个单独的线程中调用它的事件处理程序 Elapsed



但你不能打电话给任何东西与非UI线程的UI相关。相反,您需要使用 Invoke System.Windows.Threading的方法。 Dispatcher (对于Forms或WPF)或 System.Windows.Forms.Control (仅限表单)。



您将在我过去的答案中找到有关其工作原理和代码示例的详细说明:

Control.Invoke()与Control.BeginInvoke() [ ^ ],

使用Treeview扫描仪和MD5的问题 [ ^ ]。



另请参阅有关线程的更多参考资料:

如何让keydown事件在不同的操作上运行vb.net中的线程 [ ^ ],

在启用禁用+多线程后控制事件未触发 [ ^ ]。



顺便说一句,在大多数情况下,最好不要使用任何计时器,而是创建一个单独的线程(或者从线程池中利用一个线程,具体取决于你正在做的事情)并调用一些方法一个循环,有一些延迟。这更安全,更容易实现。例如,如果您在上一个计时器滴答的处理尚未完成时调用新的计时器事件时处理问题,您将理解为什么。



-SA
It all goes as expected. Let's see. This type of timers invokes you handlers of its event Elapsed in a separate thread.

But you cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

By the way, in most cases it's better not to use any timers at all, and, instead, create a separate thread (or leverage one from the thread pool, depending on what you are doing) and call some method in a loop, with some delay. This is much safer and easier to implement. You will understand why if you ever, for example, dealt with the problem when a new timer event is invoked while the handling of the previous timer tick is not yet complete.

—SA


这篇关于获取InvalidCast操作异常和跨线程操作无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆