Click here to Skip to main content
15,888,610 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
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
C#
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 = "";
                }
            }
Posted
Updated 4-Apr-14 3:28am
v2
Comments
Thomas Daniels 4-Apr-14 9:28am    
What is the type of kbd?
VipinKumar Maurya 4-Apr-14 9:30am    
kbd is a object of a form.
i have declare this and its working in another method but not the one described in the question.
KeyBoardForm kbd = new KeyBoardForm();

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.
 
Share this answer
 
Comments
VipinKumar Maurya 4-Apr-14 11:06am    
I am using win forms? BTW Can you elaborate some thing more??
Sergey Alexandrovich Kryukov 4-Apr-14 11:30am    
Vipin,

Don't use this advice to use System.Window.Forms.Timer for any purpose which require any accuracy at all, use other timers, or use my advice on threads, which allows you to take real time from the system and act accordingly. System.Window.Forms.Timer can be uses for some purpose like showing something with big delay (so, maybe this is your case). This type of timer already delegates the handler to the user thread; I think this benefit is negligibly small. I explained in detail what you can do.

—SA
Rob Philpott 4-Apr-14 11:55am    
Your arrogance is taking over again. Look at the code, he is performing a one minute update. The WinForms timer is entirely the correct choice in this case, NOT to use a threading based timer and post to the GUI thread.
Sergey Alexandrovich Kryukov 5-Apr-14 1:53am    
Calm down and please, keep to the matter of discussion, don't get stuck at personal characteristics.
My comment was two-fold. You could have noticed that I admitted that the OP's case could be one of the rare cases when this timer could be useful; and you could have noticed that my advice was actually conditional.
—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
 
Share this answer
 
Comments
VipinKumar Maurya 4-Apr-14 23:46pm    
Can I have 2 timers alive throughout the project???If not then what is the alternative to do?
Sergey Alexandrovich Kryukov 5-Apr-14 0:30am    
You can have two timers. Alternatives: 1) two threads instead; 2) one thread doing the look timed as two timers, 3) 1 timer and one thread instead of second one.
—SA
VipinKumar Maurya 5-Apr-14 1:04am    
Can you add some code to explain?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900