.NET Framework - Application.DoEvents() Equivalent in a Windows Service.

Asked By Tino Donderwinkel on 21-Mar-08 04:48 AM
I have a Windows Forms application that I'm 'converting' into a Windows
Service.

In order for the service to stop, I have to wait for an object to change
it's state. In the windows forms application I have something like;

while (myobject.state != objectstate.finished) {
Application.DoEvents();
}

I also have a Callback function in the object, that is called when its state
changes to 'finished'.

In the equivalent Windows Service, I cannot use Application.DoEvents()
because it requires the System.Windows.Forms namespace.

I have tried Thread.Sleep(1000) or something, but doing that will stall
'everything'.

Any ideas how I can solve this in a Windows Service?

This code is in the "Stop()" method of the service; I need to wait for
either the Callback to happen or the state to change to 'finsihed' before
returning from the Stop().

Tino Donderwinkel
Exchange Server MVP




BlackWasp replied on 21-Mar-08 05:02 AM
Hi Tino,

Application.DoEvents is used to make form elements redraw during processes
that are preventing the form painting events to be raised.  You should not
need to do do this in a windows service because generally there is no
forms-based interface.  (You can have windows forms in an interactive
service but then you would also have a reference to the relevant assembly).

Can you explain why you want to call DoEvents in a service so we can give
advice?

--

BlackWasp
www.blackwasp.co.uk
Tino Donderwinkel replied on 21-Mar-08 05:18 AM
Hi,

Thanks for the quick response.

I am writing a new Windows Service, based on one I made previously, but
since debugging Windows Services is somewhat of a pain, I moved all the code
to a Windows Forms application for the time being. Now I want to move
everything back to the Windows Service.

Since a Windows Forms application does not know about OnStart() and
OnStop(), I have create 2 buttons to 'simulate' the service's start and stop
events.

The 'Service' use a lot of unmanaged threads etc. Therefore, I created a
class I call a 'Dispatcher' that keeps track of all threads etc. In the
service's OnStop() event, I will eventually call 'Dispatcher.Stop()'. The
Dispatcher then enters a stopping state; it will finish working threads, but
not create new ones. I have to wait for all current threads to finish.

There is a callback function I use. If the Dispatcher is finished
processing, it will trigger the callback function.

So, in the services OnStop() event, after the Dispatcher.Stop() call, I have
to wait for the callback to arrive OR for the Dispatcher to enter a Stopped
state. (Both are primarily the same.)

How can I wait for the Dispatcher to enter the stopped state? I cannot
return from the OnStop() method before all threads are really finished.

This is the code in the OnStop() method in the Windows Forms application;

protected override void OnStop()
{
_Stopping = true;
HandleEvent("Service is stopping.",
EventLogEntryType.Information, 1103);
Dispatcher.Stop();
while (Dispatcher.State != DispatcherState.Stopped)
{
Application.DoEvents();
}
HandleEvent("Service stopped successfully.",
EventLogEntryType.Information, 1104);
}

This is the code for the Dispatcher Callback in the Windows Forms
application:

private void DispatcherDone_Callback()
{
if (!_Stopping)
{
HandleEvent("Dispatcher stopped unexpectedly.",
EventLogEntryType.Error, 7001);
OnStop();
}
}

Any ideas how to wait for the dispatcher to stop in a Windows Serivce? Can I
use something like Thread.Sleep(1000)? Not too nice, but it might work. It
will lock up the Windows Forms application though....

Tino
Ben Voigt [C++ MVP] replied on 21-Mar-08 10:52 AM
With an event.  See EventWaitHandle.