I'm developing an application which periodically polls a web service for some data. The application has to run as a Windows service, thus it has to be started and stopped in an asynchronous way. I'm using threading for this.

The main loop of the worker thread acts this way:

bool stop = false;
int interval = 60000;    // 60 seconds, customizable

while(!stop)
{
    try
    {
        // Query the web service using a WebRequest
    }
    catch(Exception e)
    {
        // Handle exception
    }

    // Process data

    try
    {
        Thread.Sleep(interval);
    }
    catch(ThreadInterruptedException)
    {}
}

To stop the worker thread, I do this from a controlling thread:

stop = true;
workerthread.Interrupt();
workerthread.Join();

This works perfectly... unless by chance the worker thread happens to be performing (or has yet to perform) a web request when Thread.Interrupt() is called; in this case, what gets actually interrupted is the web request (which presumably sleeps on its own), and the next Sleep() has to wait until its regular timeout to exit.

What is a better way to accomplish this and avoid interrupting the worker thread in the wrong place?

有帮助吗?

解决方案

Use a MaualResetEvent:

In the class that launches the thread:

ManualResetEvent evt = new ManualResetEvent(false);

Then modify your code to be:

int interval = 60000;    // 60 seconds, customizable

while(evt.WaitOne(interval))
{
    try
    {
        // Query the web service using a WebRequest
    }
    catch(Exception e)
    {
        // Handle exception
    }

    // Process data
}

To stop the thread, just call evt.Set();

This will cause the thread to stop even even if it is in the middle of the 60 second wait.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top