Re: Monitoring Threads
"Eames, Andrew" <[email protected]>
| Newsgroups | gmane.comp.windows.devel.dotnet.winforms |
|---|---|
| Message-ID | <[email protected]> |
A better solution might be to use the WindowsFormsSynchronizationContext which was introduced (pretty quietly I might add) in 2.0 There is an example of its use at http://blogs.msdn.com/mattdotson/archive/2006/02/13/531315.aspx Andrew -----Original Message----- From: Discussion forum for developers using Windows Forms to build apps and controls [mailto:[email protected]] On Behalf Of Fabian Schmied Sent: Thursday, March 29, 2007 7:51 AM To: [email protected] Subject: Re: [DOTNET-WINFORMS] Monitoring Threads > Thanks for this info. How do I get around this in the dll? Peter Ritchie > said to use a System.Forms.Timer. Can I use that in a dll that does not > have a GUI? You need to have some connection to a GUI - after all, you only have this problem because you want to update GUI controls ont hat timer event. I can think of three easy options: 1 - With System.Windows.Forms.Timer, as Peter and Patrick suggested. This might yield a few problems in a generic DLL, see below. Create a custom control which hosts a System.Windows.Forms.Timer. When you get a reference to the GUI whose controls you must update, you add this custom control to one of the GUI elements (a form or a control). Make it invisible or with zero width and height so that it doesn't create a visual problem. By having placed the control into the GUI element, the timer will fire on the right UI thread. Possible problem 1: When the GUI element hosting your custom control is disposed, the timer is as well - you might need to work around this. Possible problem 2: There might be more than one UI thread in an application, so you might need to use more than one custom control + timer. Also, it's a quite hacky. 2 - With System.Timers.Timer and Timer.SynchronizingObject. AFAICS, this has not yet been suggested. Might have the same problems as the Forms.Timer approach above, but is much cleaner. Use your System.Timers.Timer and set its Timer.SynchronizingObject to any of the controls you need to update. Problems 1 and 2 of the Forms.Timer approach (disposing, more than one UI thread) still apply. 3 - With Control.BeginInvoke, as Vince has suggested. In my opinion, this is the best option for a generic DLL. Use your System.Timers.Timer (or System.Threading.Timer, doesn't matter) and for every control or form you need to modify, be sure to BeginInvoke the modifications on that control or form. For example: private void timer_Elapsed(object source, ElapsedEventArgs e) { forach (Control c in _controls) { Debug.Assert(c.InvokeRequired, "Should always be a background thread."); c.BeginInvoke(delegate { SetControlProperties(c); }); } } I can see no problems with that approach. In case you don't have any Control references, because the objects you change aren't necessarily GUI elements, do as Patrick suggests in his second mail - let the GUI elements do the BeginInvoking. Fabian