Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread not waking up from Thread.Sleep()

We have a Windows Service written in C#. The service spawns a thread that does this:

private void ThreadWorkerFunction()
{
  while(false == _stop) // stop flag set by other thread
  {
    try
    {
      openConnection();

      doStuff();

      closeConnection();
    }
    catch (Exception ex)
    {
      log.Error("Something went wrong.", ex);

      Thread.Sleep(TimeSpan.FromMinutes(10));
    }
  }
}

We put the Thread.Sleep in after a couple of times when the database had gone away and we came back to 3Gb logs files full of database connection errors.

This has been running fine for months, but recently we've seen a few instances where the log.Error() statement logs a "System.InvalidOperationException: This SqlTransaction has completed; it is no longer usable" exception and then never ever comes back. The service can be left running for days but nothing more will be logged.

Having done some reading I know that Thread.Sleep is not ideal, but why would it simply never come back?

like image 748
d4nt Avatar asked Aug 27 '08 10:08

d4nt


2 Answers

Dig in and find out? Stick a debugger on that bastard!

I can see at least the following possibilities:

  1. the logging system hangs;
  2. the thread exited just fine but the service is still running because some other part has a logic error.

And maybe, but almost certainly not, the following:

  • Sleep() hangs.

But in any case, attaching a debugger will show you whether the thread is still there and whether it really has hung.

like image 141
Sander Avatar answered Nov 15 '22 23:11

Sander


We put the Thread.Sleep in after a couple of times when the database had gone away and we came back to 3Gb logs files full of database connection errors.

I would think a better option would be to make it so that your logging system trapped duplicates, so that it could write something like, "The previous message was repeated N times".

Assume I've written a standard note about how you should open your connection at the last possible moment and close it at the earliest opportunity, rather than spanning a potentially huge function in the way you've done it (but perhaps that is an artefact of your demonstrative code and your application is actually written properly).

When you say that it's reporting the error you describe, do you mean that this handler is reporting the error? The reason it's not clear to me is that in the code snippet you say "Something went wrong", but you didn't say that in your description; I wouldn't want this to be something so silly as the exception is being caught somewhere else, and the code is getting stuck somewhere other than the sleep.

like image 3
DrPizza Avatar answered Nov 15 '22 23:11

DrPizza