Re: Monitoring Threads

Fabian Schmied <[email protected]>
Newsgroups gmane.comp.windows.devel.dotnet.winforms
Message-ID <[email protected]>
> 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.