Re: Monitoring Threads
Peter Ritchie <[email protected]>
| Newsgroups | gmane.comp.windows.devel.dotnet.winforms |
|---|---|
| Message-ID | <LISTSERV%[email protected]> |
Using WindowsFormsSynchronizationContext still couples the existence of a form to this library code and presupposes there is a form (which may not be the case). To be completely agnostic about forms, I would suggest using the AsyncOperationManager [1] class. The thread that calls AsyncOperationManager.CreateOperation is the thread that is used for progress, incremental results and completed event handler calls. [1] http://msdn2.microsoft.com/en- us/library/system.componentmodel.asyncoperationmanager.aspx On Thu, 29 Mar 2007 09:02:07 -0400, Eames, Andrew <[email protected]> wrote: >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.