Why thread enters WaitSleepJoin state? - c#

I'm coding singleton class that runs a background thread. Here is how it started and maintained:
private void EnsureBackgroundThread()
{
try
{
if (this.RunnerThread == null)
this.RunnerThread = new Thread(this.BackgroundRunner) { IsBackground = true };
if (this.RunnerThread.ThreadState != ThreadState.Running)
{
Debug.WriteLine("----ApplePushNotificatorService.EnsureBackgroundThread ThreadState: " + this.RunnerThread.ThreadState);
this.RunnerThread.Start();
}
}
catch (Exception ex)
{
this.LoggerService.Log(null, ex);
}
}
I call my method in this class from TestClass like so:
apns.Send("dev", devices, "Testing...", out badIds);
// Wait 5 seconds to let it send stuff through.
Thread.Sleep(5000);
devices.Clear();
devices.Add("some bad id");
// Now let's call this again, but this time we should get back some bad Ids
apns.Send("dev", devices, "Testing...", out badIds);
// Wait 5 seconds to let it send stuff through.
Thread.Sleep(5000);
devices.Clear();
devices.Add("9edc21d0d4e369f50040c5d2c94f2ea29c7d596090e4ddae253712cd406391df");
apns.Send("dev", devices, "Test message for Andrew's phone", out badIds);
// Wait 5 seconds to let it send stuff through.
Thread.Sleep(5000);
I checked error logs and I see exceptions:
Thread is running or terminated; it cannot restart.
In debug it says:
----ApplePushNotificatorService.EnsureBackgroundThread ThreadState: Background, WaitSleepJoin
Why does it enter "WaitSleepJoin" state? Is it because I do "Thread.Sleep" in my test?
Does my code to keep thread alive look correct? How do I work around this? The idea is when "Send" method called on singleton - we need to make sure background thread is running.
EDIT:
This is re-worked code that is working properly
private void EnsureBackgroundThread()
{
try
{
if (this.RunnerThread != null && this.RunnerThread.IsAlive) return;
this.RunnerThread = new Thread(this.BackgroundRunner) { IsBackground = true };
this.RunnerThread.Start();
}
catch (Exception ex)
{
this.LoggerService.Log(null, ex);
}
}

The state tells us that the thread is currently sleeping, likely in one of your calls to Sleep. This means it's still running. Because it's still running, you cannot start it. You're trying to start the same thread multiple times. You can't do that. You start it once, then it's started, and that's that. Trying to start it a second time, either while it's running, or after it is done, is not possible.

Quite simply, as the error states: your thread has been created and is running or terminated - and then you try to start it again.
Presumably in your TestClass you have multiple calls to your singleton class (I'm guessing this may be somewhere under the apns.Send call). The first time you call EnsureBackgroundThread, a single thread will be created and started. The next time you call EnsureBackgroundThread will call Thread.Start on the same thread, thus causing the same error.
It's perhaps important to note here that, when a thread completes, the variable referencing it isn't set to null - but more likely you're just calling the EnsureBackgroundThread method more than once and the code you've written doesn't support that.

Related

How to terminate a thread when the worker can't check the termination string

I have the following code running in a Windows form. The method it is calling takes about 40 seconds to complete, and I need to allow the user the ability to click an 'Abort' button to stop the thread running.
Normally I would have the Worker() method polling to see if the _terminationMessage was set to "Stop" but I can't do this here because the long running method, ThisMethodMightReturnSomethingAndICantChangeIt() is out of my control.
How do I implement this user feature please ?
Here is my thread code.
private const string TerminationValue = "Stop";
private volatile string _terminationMessage;
private bool RunThread()
{
try
{
var worker = new Thread(Worker);
_terminationMessage = "carry on";
_successful = false;
worker.Start();
worker.Join();
finally
{
return _successful;
}
}
private void Worker()
{
ThisMethodMightReturnSomethingAndICantChangeIt();
_successful = true;
}
Well, the simple answer would be "you can't". There's no real thread abort that you can use to cancel any processing that's happenning.
Thread.Abort will allow you to abort a managed thread, running managed code at the moment, but it's really just a bad idea. It's very easy to end up in an inconsistent state just because you were just now running a singleton constructor or something. In the end, there's quite a big chance you're going to blow something up.
A bit orthogonal to the question, but why are you still using threading code like this? Writing multi-threaded code is really hard, so you want to use as many high-level features as you can. The complexity can easily be seen already in your small snippet of code - you're Joining the newly created thread, which means that you're basically gaining no benefit whatsoever from starting the Worker method on a new thread - you start it, and then you just wait. It's just like calling Worker outright, except you'll save an unnecessary thread.
try will not catch exceptions that pop up in a separate thread. So any exception that gets thrown inside of Worker will simply kill your whole process. Not good.
The only way to implement reliable cancellation is through cooperative aborts. .NET has great constructs for this since 4.0, CancellationToken. It's easy to use, it's thread-safe (unlike your solution), and it can be propagated through all the method chain so that you can implement cancellation at depth. Sadly, if you simply can't modify the ThisMethodMightReturnSomethingAndICantChangeIt method, you're out of luck.
The only "supported" "cancellation" pattern that just works is Process.Kill. You'd have to launch the processing method in a wholy separate process, not just a separate thread. That can be killed, and it will not hurt your own process. Of course, it means you have to separate that call into a new process - that's usually quite tricky, and it's not a very good design (though it seems like you have little choice).
So if the method doesn't support some form of cancellation, just treat it like so. It can't be aborted, period. Any way that does abort it is a dirty hack.
Well, here's my solution so far. I will definitely read up on newer .NET higher level features as you suggest. Thanks for the pointers in the right direction
private void RunThread()
{
try
{
var worker = new Thread(Worker);
SetFormEnabledStatus(false);
_usuccessful = false;
worker.Start();
// give up if no response before timeout
worker.Join(60000); // TODO - Add timeout to config
worker.Abort();
}
finally
{
SetFormEnabledStatus(true);
}
}
private void Worker()
{
try
{
_successful= false;
ThisMethodMightReturnSomethingAndICantChangeIt();
_successful = true;
}
catch (ThreadAbortException ex)
{
// nlog.....
}
catch (Exception ex)
{
// nlog...
}
}

TryTake Performance on blockingcollection

I have a programm which sometimes runs significantly slow.
I tried Teleriks Justtrace to find out, what could possible cause a hang of the application.
A non UI thread (therefore I believe it's not really the cause of the hang) does assync. get objects (Enqueues workitems) and deques it to do some work.
Enqueue:
public void EnqueueObject(WorkUnit workunit)
{
try
{
workUnits.Add(workunit);
}
catch (Exception ex)
{
/handle exception
}
}
Dequeue:
public WorkUnit Dequeue()
{
try
{
WorkUnit aWorkUnit = null;
workUnits.TryTake(out aWorkUnit, 1000);
return aWorkUnit ;
}
catch (InvalidOperationException ex)
{
//
}
return null;
}
TryTake was used to check for an abort of current work (instead of the BlockingCollection Complete method which just throws some errors when called - i don't want to use errors for programm flow)
Call to dequeue:
while(!isStopped)
{
ProcessWorkItem(Dequeue());
}
Up to here it looks quite simple.
The problem is, that Teleriks JustTrace shows, that the line "workUnits.TryTake(out aWorkUnit, 1000);" takes 30% of the total execution time of the program.
How can this be?
With more details it shows that inside the TryTake System.Threading.Monitor.Wait takes up all the time - i thought the Wait would send a thread to sleep, so it does not consume something during the wait. Where is the error in the thought?
You can try using workUnits.TryTake(out aWorkUnit) without the timeout parameter. And then, you should modify while loop to look similar to this:
while(!isStopped)
{
WorkUnit wu = Dequeue();
if(wu != null)
ProcessWorkItem(wu);
else
Thread.Sleep(40);
}
Also, if you are running this code on a UI thread it will make your UI unresponsive. You should use for example BackgroundWorker for the operation. Here's the description of BackgroundWorker class from MSDN documentation:
The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as though it has stopped responding while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker class provides a convenient solution.

Thread executing remote connection won't abort

I'm designing a small program whose objective is to make sure one of our server is up and running. In some cases, the server won't answer and a script must be launched to restart the server.
First I'm starting a new thread responsible of fetching the information, which is then joined by the main thread for a certain time span. I then abort the thread to disconnect and finally join it to leave enough time to execute the catch and finally blocks.
In theory it should work great : if the time span is short enough, it indeed indicates that the server is down (because no connection could be made in the short allocated timespan). But in certain cases, when the server is really down, the program will just keep executing, as if the ThreadAbortException had no effect. Problem is, these downtimes are quite sporadic so I couldn't debug it myself to see what was not working properly.
Here's how it goes :
This here is the main thread, calling the worker thread. Very straightforward.
public void LaunchCommand()
{
Thread pingThread = new Thread(new ThreadStart(Ping));
pingThread.Start();
while (!pingThread.IsAlive);
pingThread.Join(new TimeSpan(0, 0, _maxTime));
pingThread.Abort(); // Time's up.
pingThread.Join(); // Make sure we complete everything before moving on
}
And here's the called thread :
private void Ping()
{
try
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
serviceType = Type.GetTypeFromProgID(serviceProgID, _server, true);
service = Activator.CreateInstance(serviceType);
_xmlResult = ApxServiceType.InvokeMember("ExecuteXML", BindingFlags.InvokeMethod, null, service, new string[] { _dataset, Command, string.Empty }) as string;
stopwatch.Stop();
_latency = stopwatch.Elapsed;
// Trivial validations to make sure _status is true, such as _xmlResult.Contains(certainSubString); and such
_status = true; // Everything seems to work fine if we could make up to here.
}
catch (ThreadAbortException)
{
Console.WriteLine("Server timeout :(");
return;
}
catch (Exception e)
{
Console.WriteLine("Server exception: " + e.Message);
return;
}
finally
{
if (!_status)
{
_latency = new TimeSpan(0, 0, _maxTime);
}
}
}
Variables such as Commands, serviceProgID, etc. have been declared elsewhere and are known to work well. I guess my problem spans from the three lines following the stopwatch declaration/initialization. First, I must say I copy pasted these lines from a similar application, but basically it should only fetch a result from the given Command. Unfortunately, because I couldn't debug under the critical situation, I don't which line is problematic, but anyway, it seems the ThreadAbortException has no effect. Is it because code has been switched off to unmanaged?
I'm lost here so any idea would be welcomed! Thanks!
I actually don't see a need to use a separate thread for your scenario. You may check for server availability using synchronous operation. Does the function being used to check server availability offer timeout option? If yes then the timeout option should be enough. If the function returns before the timeout then it means server is online otherwise server is down.
If the function for checking server availability does not offer timeout option and may cause the thread to wait forever (or for a long time) then you may use a new thread. However if Thread.Join(Timeout) method returns true and _status variable is also true then you can be certain that the server is online. If Thread.Join(Timeout) returns false then it would mean that the server is down.
As a good practice, you should use Thread.ResetAbort in the catch block handling Abort exception. Otherwise runtime will rethrow the ThreadAbort exception once catch block finishes execution.

Thread.Join in UI thread also blocking child thread

This may well be a dumb question and if this has already been answered elsewhere then I'd really appreciate it if someone could point me to it as my searching hasn't turned up anything definitive.
In a nutshell, my problem is that when I do childThread.Join() in the UI thread on a child thread which has been flagged to stop the childThread seems to block as well as the main thread so everything just hangs.
That the UI will block due to using Join is not a problem in and of itself at the moment since the childThread should finish in under a second after it's told to quit anyway.
This happens while I'm waiting for a thread running a repeating process to quit before I can run another method which returns some information but can't be run at the same time as the other process.
My Winforms application is integrating with a piece of usb hardware by pinvoking the C API for the hardware.
The hardware API has a method that will start off a process that will run indefinitely and repeatedly and rapidly callback with new information which I then need to pass to the UI.
This operation can be cancelled by another call to the hardware API which sets a flag the hardware can see so it knows to quit.
I've wrapped this C API with my own C# code, and within the wrapper I've had to spin out the start process call in another thread so that the activity doesn't block the UI.
Here are the edited highlights of roughly what I'm doing.
public class DeviceWrapper
{
Thread childThread = null;
void DeviceWrapper
{
//Set the callback to be used by the StartGettingInformation() process
PInvokeMethods.SetGetInformationCallback(InformationAcquiredCallback);
}
public void StartProcess()
{
childThread = new Thread(new ThreadStart(GetInformationProcess))
childThread.Start();
}
void GetInformationProcess()
{
PInvokeMethods.StartGettingInformation();
}
//This callback occurs inside the childThread
void InformationAcquiredCallback(Status status, IntPtr information)
{
//This callback is triggered when anything happens in the
//StartGettingInformation() method, such as when the information
//is ready to be retrieved, or when the process has been cancelled.
if(status == Status.InformationAcquired)
{
FireUpdateUIEvent();
}
//If the cancel flag has been set to true this will be hit.
else if(status == Status.Cancelled)
{
//Reset the cancel flag so the next operation works ok
PInvokeMethods.SetCancelFlag(false);
childThread.Abort();
}
}
//This method runs once, and can't run at the same time as GetInformationProcess
public string GetSpecificInformation()
{
//This triggers InformationAcquiredCallback with a status of Cancelled
StopProcess();
if(childThread.IsAlive)
{
childThread.Join();
}
return PInvokeMethods.GetSpecificInformation();
}
public void StopProcess()
{
PInvokeMethods.SetCancelFlag(true);
}
}
Using this code when I call childThread.Join() the whole application grinds to a halt (which I'd expect for the UI and that's fine) and the childThread also seems to halt because the callback never gets hit again.
However, if I use the following code instead:
public string GetSpecificInformation()
{
//This triggers InformationAcquiredCallback with a status of Cancelled
StopProcess();
string s = "";
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
{
if(childThread.IsAlive)
{
childThread.Join();
}
s = PInvokeMethods.GetSpecificInformation();
}));
return s;
}
Then everything gets hit as expected and childThread does finish and all is well, except obviously my string gets returned empty before the WaitCallback fires and assigns to it.
So, do I just have to suck it up and change the class so that I use the QueueUserWorkItem and WaitCallback and fire an event to deal with my string return?
Is there something daft I'm doing in my first approach that's causing the childThread to block as well?
Or is there another tactic or class entirely that I should be using, bearing in mind it's .NET 3.5 I'm on?
Well, FireUpdateUIEvent(); sounds like a method that might Post Send to the MsgQueue (Control.Invoke()). When the main thread is waiting in a Join() then you have a classic deadlock.
In Addition, childThread.Abort() is not considered safe.
So, do I just have to suck it up and change the class so that I use the QueueUserWorkItem and WaitCallback and fire an event to deal with my string return?
I certainly would re-design it. It probably can be simplified a bit.

how do set a timeout for a method

how do set a timeout for a busy method +C#.
Ok, here's the real answer.
...
void LongRunningMethod(object monitorSync)
{
//do stuff
lock (monitorSync) {
Monitor.Pulse(monitorSync);
}
}
void ImpatientMethod() {
Action<object> longMethod = LongRunningMethod;
object monitorSync = new object();
bool timedOut;
lock (monitorSync) {
longMethod.BeginInvoke(monitorSync, null, null);
timedOut = !Monitor.Wait(monitorSync, TimeSpan.FromSeconds(30)); // waiting 30 secs
}
if (timedOut) {
// it timed out.
}
}
...
This combines two of the most fun parts of using C#. First off, to call the method asynchronously, use a delegate which has the fancy-pants BeginInvoke magic.
Then, use a monitor to send a message from the LongRunningMethod back to the ImpatientMethod to let it know when it's done, or if it hasn't heard from it in a certain amount of time, just give up on it.
(p.s.- Just kidding about this being the real answer. I know there are 2^9303 ways to skin a cat. Especially in .Net)
You can not do that, unless you change the method.
There are two ways:
The method is built in such a way that it itself measures how long it has been running, and then returns prematurely if it exceeds some threshold.
The method is built in such a way that it monitors a variable/event that says "when this variable is set, please exit", and then you have another thread measure the time spent in the first method, and then set that variable when the time elapsed has exceeded some threshold.
The most obvious, but unfortunately wrong, answer you can get here is "Just run the method in a thread and use Thread.Abort when it has ran for too long".
The only correct way is for the method to cooperate in such a way that it will do a clean exit when it has been running too long.
There's also a third way, where you execute the method on a separate thread, but after waiting for it to finish, and it takes too long to do that, you simply say "I am not going to wait for it to finish, but just discard it". In this case, the method will still run, and eventually finish, but that other thread that was waiting for it will simply give up.
Think of the third way as calling someone and asking them to search their house for that book you lent them, and after you waiting on your end of the phone for 5 minutes you simply say "aw, chuck it", and hang up. Eventually that other person will find the book and get back to the phone, only to notice that you no longer care for the result.
This is an old question but it has a simpler solution now that was not available then: Tasks!
Here is a sample code:
var task = Task.Run(() => LongRunningMethod());//you can pass parameters to the method as well
if (task.Wait(TimeSpan.FromSeconds(30)))
return task.Result; //the method returns elegantly
else
throw new TimeoutException();//the method timed-out
While MojoFilter's answer is nice it can lead to leaks if the "LongMethod" freezes. You should ABORT the operation if you're not interested in the result anymore.
public void LongMethod()
{
//do stuff
}
public void ImpatientMethod()
{
Action longMethod = LongMethod; //use Func if you need a return value
ManualResetEvent mre = new ManualResetEvent(false);
Thread actionThread = new Thread(new ThreadStart(() =>
{
var iar = longMethod.BeginInvoke(null, null);
longMethod.EndInvoke(iar); //always call endinvoke
mre.Set();
}));
actionThread.Start();
mre.WaitOne(30000); // waiting 30 secs (or less)
if (actionThread.IsAlive) actionThread.Abort();
}
You can run the method in a separate thread, and monitor it and force it to exit if it works too long. A good way, if you can call it as such, would be to develop an attribute for the method in Post Sharp so the watching code isn't littering your application.
I've written the following as sample code(note the sample code part, it works, but could suffer issues from multithreading, or if the method in question captures the ThreadAbortException would break it):
static void ActualMethodWrapper(Action method, Action callBackMethod)
{
try
{
method.Invoke();
} catch (ThreadAbortException)
{
Console.WriteLine("Method aborted early");
} finally
{
callBackMethod.Invoke();
}
}
static void CallTimedOutMethod(Action method, Action callBackMethod, int milliseconds)
{
new Thread(new ThreadStart(() =>
{
Thread actionThread = new Thread(new ThreadStart(() =>
{
ActualMethodWrapper(method, callBackMethod);
}));
actionThread.Start();
Thread.Sleep(milliseconds);
if (actionThread.IsAlive) actionThread.Abort();
})).Start();
}
With the following invocation:
CallTimedOutMethod(() =>
{
Console.WriteLine("In method");
Thread.Sleep(2000);
Console.WriteLine("Method done");
}, () =>
{
Console.WriteLine("In CallBackMethod");
}, 1000);
I need to work on my code readability.
Methods don't have timeouts in C#, unless your in the debugger or the OS believes your app has 'hung'. Even then processing still continues and as long as you don't kill the application a response is returned and the app continues to work.
Calls to databases can have timeouts.
Could you create an Asynchronous Method so that you can continue doing other stuff whilst the "busy" method completes?
I regularly write apps where I have to synchronize time critical tasks across platforms. If you can avoid thread.abort you should. See http://blogs.msdn.com/b/ericlippert/archive/2010/02/22/should-i-specify-a-timeout.aspx and http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation for guidelines on when thread.abort is appropriate. Here are the concept I implement:
Selective execution: Only run if a reasonable chance of success exists (based on ability to meet timeout or likelihood of success result relative to other queued items). If you break code into segments and know roughly the expected time between task chunks, you can predict if you should skip any further processing. Total time can be measured by wrapping an object bin tasks with a recursive function for time calculation or by having a controller class that watches workers to know expected wait times.
Selective orphaning: Only wait for return if reasonable chance of success exists. Indexed tasks are run in a managed queue. Tasks that exceed their timeout or risk causing other timeouts are orphaned and a null record is returned in their stead. Longer running tasks can be wrapped in async calls. See example async call wrapper: http://www.vbusers.com/codecsharp/codeget.asp?ThreadID=67&PostID=1
Conditional selection: Similar to selective execution but based on group instead of individual task. If many of your tasks are interconnected such that one success or fail renders additional processing irrelevant, create a flag that is checked before execution begins and again before long running sub-tasks begin. This is especially useful when you are using parallel.for or other such queued concurrency tasks.

Categories

Resources