I am using VS 2012, .Net 4.5.
Execute this code (just upgrade some sample from article about threading):
using System.Threading;
class BasicWaitHandle
{
static EventWaitHandle wh = new AutoResetEvent(false);
static void Main()
{
new Thread(Waiter).Start();
new Thread(Waiter).Start();
Thread.Sleep(1000); // Подождать некоторое время...
wh.Set(); // OK – можно разбудить
wh.Set();
Console.ReadLine();
}
static void Waiter()
{
Console.WriteLine("Avait..."+Thread.CurrentThread.ManagedThreadId);
wh.WaitOne(); // Ожидать сигнала
Console.WriteLine("Got a signal"+Thread.CurrentThread.ManagedThreadId);
}
}
I Debug it few times, but usually (not always) get wrong result. At first (once or more times) it correct:
Avait...10
Avait...11
Got a signal 11
Got a signal 10
But then it just start skipping one thread (somethimes first? somethimes second):
Avait...10
Avait...11
Got a signal 11 (or 10)
And program just does not react. In a few minutes it gives some correct results, but then go wrong again...
Moreover, when i debugging it step-by-step it always acting correctly.
So, maybe I should choose another approach? But this looks like what I expected, even if threads got signals in random order...
I am pretty unsure you can use same AutoResetEvent for multiple awaters, because Set is not waiting for first thread to complete its Wait:
There is no guarantee that every call to the Set method will release a thread from an EventWaitHandle whose reset mode is EventResetMode.AutoReset. If two calls are too close together, so that the second call occurs before a thread has been released, only one thread is released. It is as if the second call did not happen. Also, if Set is called when there are no threads waiting and the EventWaitHandle is already signaled, the call has no effect.
I'd go with ManualResetEvent and synchronization during setting signal (to ensure, what waiting thread receive signal) or (better) use dedicated event for each waiting function (every thread would start with its own event to wait for, you will need kind of manager for those thread to create waiting event and to have Set method what will signal all these events).
p.s.: can repeat said above in russian btw ^^
Both threads start and run until they block on the WaitHandle. When the WaitHandle is set, one thread will wake up and the event will reset.
You can't guarantee which thread will wake up, so the order isn't ensured. When running correctly, either 10 or 11 will wake up, followed by the other, every time.
In the case where your application hangs, the problem is the execution order. The main thread is executing both calls to Event.Set() prior to the first thread waking up. The AutoResetEvent is not a counter, it is either set or unset, so the second call to Set() is lost.
If you Sleep() between calls to Set(), you will yield to the other threads and give one of them time to wake up and reset the event.
In the case where it works correctly, you are just getting lucky and the waiting threads are getting a chance to run between calls to Set(). This is referred to as a race condition.
Related
I'm using the System.Threading.Thread object to create a background-working method. The method loads data which can also be used by the user in the current time (must be read from the same source). That's why I'd like to find the created Thread and pause it for the time of current data-loading.
Here comes the problem... How to find the Thread?
I've already read about System.Diagnostics.Process attempt, but it contains data only about the OS-Threads.
Also I need to say that the method starting the Thread is static and it's possible but really unwanted to create an object to track the thread. I'm just creating new object and starting it...
(new Thread(new ThreadStart(...))).Start();
I've looked through many topic but I found no following question:
IF IT'S IMPOSSIBLE, THAN FROM WHERE THE VISUAL STUDIO -> THREAD WINDOW TAKES INFORMATION!?
Thanks in advance for any help :)
If pausing the "reading" thread is truly required, you can have it wait for a signal using the EventWaitHandle class, set as Manual or Automatic reset depending on your use case, starting unset. The background thread, when it has finished writing to whatever the shared variable location is, can set the signal on the wait handle to release the "reading" thread that was stuck waiting.
If your "reading" thread only needs to pause sometimes, you can use the same wait handle approach, except have it start as "set" in Manual Reset mode while your "reading" thread checks it whenever appropriate. The "reading" thread will skip over waiting for the signal (because it's already set)!
Once your "writing" thread needs to make a change, it would reset the wait handle, causing your "reading" thread to pause when it checks for the signal, update the data, then "set" the signal again to release the paused "reading" thread.
Use Task for background work and you can utilize Continue method to process the data on completion of task.
var task = Task.Run(() => "Test");
task.ContinueWith((str) => "Process data");
Or utilize Name property of Thread class to assign the name.
I create some threads to do some work using threadpool. Every thread increments finishedThreads variable, so the main thread knows when all the threadpool threads terminate:
// in the main thread
while (finishedThreads < threadsNumber) {
// wait
}
// threads terminated, we can continue
// last line of the threadpool thread
++finishedThreads;
Everything works fine until I create a big amount of threads - over 50. Then the last thread never terminates, so the finishedThreads is still equal threadsNumber-1 and the main thread never continues. I tried to find out why this happens, using debugging, stopping Visual etc. but nothing helped. The thread is not being terminated, although as Visual shows, it does not execute any code. Have you got any ideas on what goes wrong? Thanks in advance.
[EDIT]: That's how I create new threads:
ThreadPool.QueueUserWorkItem(new WaitCallback(myThreadFunc), someData);
I have a weird issue:
In my C# app, I am creating another thread, like so:
Thread printThread = new Thread(printWorker);
printThread.Name = "Logger MainThread";
printThread.IsBackground = true;
printThread.Start();
When my main thread finishes, this new thread just keeps on working, although it's marked as Background.
What could be the causes for this?
This object is holding a Mutex object, not sure this may be the reason...
Any ideas anyone?
Here's the code from the printWorker method:
while (loggerIsActive)
{
LogMessage log = LoggerQueue.Dequeue();
if (log.message != null)
{
syncLogObj.WaitOne();
lock (writerobj)
{
StreamWriter sw;
if (!File.Exists(fName))
{
sw = File.CreateText(fName);
}
else
{
sw = new StreamWriter(fName, true);
}
using (sw)
{
if (log.message != "")
{
if (log.message.EndsWith("\r\n"))
{
log.message =
log.message.Substring(0, log.message.Length - 2);
}
sw.WriteLine(string.Format("[{0}][{3}][{1}] | {2}",
log.msgTime,
log.level.ToString(),
log.message,
log.sender.ToString()));
}
sw.Flush();
sw.Close();
}
}
syncLogObj.ReleaseMutex();
}
Thread.Sleep(5);
}
Try this:
Start the app through VS and exit normally. The VS should stay in Debug mode as you described. Click on Pause button (Break all) and then go to Debug->Windows->Threads. Do you see your "Logger MainThread" in the list?
If so, double-click it, it should lead you to the code line that the thread is currently executing. Step-debug from there and see why is it not terminating.
If you don't see it try looking at other threads that have not terminated and try to find the problem.
Otherwise, with those kind of problems it's always useful to monitor the program state via System.Diagnostics.Debug.Print statements (you can see them printing in the VS output window).
kill it.
Not pretty. But this isn't TV. Read on:
1) Not sure you use are using it but it appears you should be locking loggerqueue before you queue(main pgm) or dequeue(thread).
2) No need to lock writerobj with just this setting. But really you should so you can safely kill the thread not during a write:
main thread:
do everything
before close:
-lock writerobj
-printthread.abort
worker thread:
add try catch to handle threadabort exception and just quit
If you're properly doing this, you shouldn't have to use Waits and mutexes. If you are using wait properly anyway you won't need the sleep.
General advice for this application: why not log on main thread? if your logging is that busy, log results will be pretty useless.
But there are rare cases where that might be wrong. Entonces......
General advice to have threads play nice for this problem:
Main program
encapsulate logging (notably, quit flag, queue, and worker thread ref) in an object
'global snobs?' Logging is a rare excuse to use singleton patter.
start worker thread in logger object via method
main thread always calls a single method on logger object to log error
That method locks the queue and adds to it.
Use Monitor/Pulse/Wait, no sleep; full examples abound; it is worth learning
because only this thread is hitting the file anyway, unless you have multiple processes, you don't need waitone/releasemutex.
That logging method monitor.pulses an object
That frees the worker thread's monitor.wait (which is what idles the CPU instead of sleep)
lock the queue, only inside the lock dequeue the object to local ref; nothing else.
Do your normal logging code and 'exit check' loop. Add
Your logic code could leave message unwritten if queue is full on quit:
change to exit check so you can do it without an extra lock of queue:
move declaration of queued object refernce above while; set it to nothing
change logic in while to 'loggerisactive or log != null'
when your main thread finishes, in your exit code:
set the quit flag
pulse the object you're using to wait incase it's not processing the queue
Thread will fall thru.
You have a lot of stuff going on that you're obviously not showing...
Exmaple: you have syncLogObj.WaitOne();, but we don't see where syncLogObj is being declared, or used elsewhere in your program.
Plus, you don't need it... get rid of the syncLogObj thing altogether (including the "ReleaseMutex" garbage)... you already have a lock (blah) { }, and that's all you need (from what code you have displayed).
It's likely that the main thread is NOT ending, likely because of this or some other object that is keeping it open.
So, simple instructions
Get rid of syncLogObj (because you already have the "lock")
Make sure you set loggerIsActive = false somewhere.
Edit: Even more details!
From what I see - you don't need the lock (writerobj) at all, because (I'm quite sure), you only seem to have one thread that is writing to the log.
The "lock" is only there if you have two or more threads that running that code (basically).
If printworker does not finish before your main thread is done, then main will die and your printworker thread will be killed by the OS. If you want main to wait for the thread you created, then you should call printThread.Join() in main. That will get main to wait on your thread.
When main finishes your program dies and your printThread will be destroyed by the OS, It will not keep running.
From here
Background threads are identical to
foreground threads with one exception:
a background thread does not keep the
managed execution environment running.
Once all foreground threads have been
stopped in a managed process (where
the .exe file is a managed assembly),
the system stops all background
threads and shuts down.
Tony the Tiger has the right idea but additional code needs to be added to kill the thread before the application closes.
printThread.Join(1000);
if(printThread!=null && printThread.IsAlive)
printThread.Abort();
Thread.Abort();
Thread.Dispose();
That should do it if I'm not mistaken.
I have a multi thread application written by c#, my max thread number is 256 and this application gets the performance counters of the computers in an Ip interval(192.168.1.0 -192.168.205.255)
it works fine and turns many times in a day. because I have to get reports.
But the problem is some times one machine keeps a thread and never finishes its work so my loop doesnt turn...
Are there any way to create threads with a countdown parameter. when I start the threads in foreach?
foreach(Thread t in threads)
{
t.start(); -----> t.start(countdownParameter) etc....
}
coundown parameter is the max life of each threads. This mean if a thread cant reach a machine it have to be abort. for example 60 seconds.. no not 256 machines, I meant 256 threads... there are about 5000 ip and 600 of them are alive. soo I am using 256 threads to read their values. and the other thing is loop. my loop is working as while all off the ipies finish it starts from beginning.
You can't specify a timeout for thread execution. However, you can try to Join each thread with a timeout, and abort it if it doesn't exit.
foreach(Thread t in threads)
{
t.Start();
}
TimeSpan timeOut = TimeSpan.FromSeconds(10);
foreach(Thread t in threads)
{
if (!t.Join(timeOut))
{
// Still not complete after 10 seconds, abort
t.Abort();
}
}
There are of course more elegant ways to do it, like using WaitHandles with the WaitAll method (note that WaitAll is limited to 64 handles at a time on most implementations, and doesn't work on STA threads, like the UI thread)
You should not terminate the thread from the outside. (Never kill a thread, make it commit suicide). Killing a thread can easily corrupt the state of an appdomain if you're not very careful.
You should rewrite the network code in the threads to either time out once the time-limit has been reached, or use asynchronous network code.
Usually a thread gets stuck on a blocking call (unless of course you have a bug causing an infinite loop). You need to identify which call is blocking and "poke" it to get it to unblock. It could be that your thread is waiting inside one of the .NET BCL waiting calls (WaitHandle.WaitOne, etc.) in which case you could use Thread.Interrupt to unblock it. But, in your case it is more likely that the API managing the communication with the remote computers is hung. Sometimes you can simply close the connection from a separate thread and that will unblock the hung method (as is the case with the Socket class). If all else fails then you really might have to fall back on the method of last of calling Thread.Abort. Just keep in mind that if you abort a thread it might corrupt the state of the app domain in which the abort originated or even the entire process itself. There were a lot of provisions added in .NET 2.0 that make aborts a lot safer than they were before, but there is still some risk.
You can use smth like this:
public static T Exec<T>(Func<t> F, int Timeout, out bool Completed)
{
T result = default(T);
Thread thread = new Thread(() => result = F());
thread.Start();
Completed = thread.Join(Timeout);
if(!Completed) thread.Abort();
return result;
}
I am aware that System.Threading.Timer exists, but I already have a Thread. This thread is supposed to stay alive all the time, but only execute every X seconds. The test implementation looks like this:
public class MailClass
{
private Action<string> LoggerAction;
private bool _exit;
public MailClass(Action<string> loggerAction)
{
LoggerAction = loggerAction;
}
public void Run()
{
LoggerAction("Run called");
_exit = false;
while(!_exit)
{
Thread.Sleep(TimeSpan.FromSeconds(300));
LoggerAction("Waking up");
}
LoggerAction("Run ended");
}
public void Stop()
{
LoggerAction("Stop called");
_exit = true;
}
}
The Run method executes, then sleeps for 5 Minutes, then executes again. So it's basically a timer that fires every 5 Minutes + the time it takes to execute the action. (and yes, I should cache the TimeSpan instead of re-creating it over and over)
Is this the proper way to do it? (In the real app, the Run action checks a Web Service, so I have no way to signal my Thread to wake up earlier)
Or should I use some other concept to have the thread? One problem I see is the implementation of Stop. The Run Thread runs a loop that checks a bool every time, but if I call Stop() I have to wait until the Sleep Interval is over, which is inconvenient.
Thread.Abort would be harsh, so I guess Thread.Interrupt would work somehow? The Stop() Method should allow Run to finish it's current iteration, so no hard abort. AutoResetEvent looks a bit like what I could need, but I don't fully understand what it does.
Edit: One way I would see this possible is to add a Timer (so a separate thread) and then have Run() end not with Thread.Sleep but with some "Wait until some object changes". I would then change that object either from the second Thread (when the 5 minutes expire) or from the Stop action. But that seems excessive? Essentially, Run needs to react to two conditions: 5 Minutes expire or some external signal (like the change of the _exit flag). Something tells me there should be something built-in, but maybe having another Timer Thread solely focused on sending a signal every 5 minutes is the way to go?
If you're forced to poll, then you're forced to poll. Thread.Sleep() is fine for that.
However with regards to you're interrupt concerns...
I'd re-write your solution a bit to use Monitor.Wait/Pulse. That does require you keep an object around solely to lock(...){} on it, but it strikes me as a cleaner solution.
I say cleaner because using Thread.Interrupt() is effectively using exceptions for "normal" control flow. Stopping a Timer is in no way unexpected. But its a design smell really (if such things exist), nothing more.
Quicky outline:
//Instead of Thread.Sleep(FIVE_MIN) in Run()...
lock(some_obj)
{
if(Monitor.Wait(some_obj, FIVE_MIN)) //Wait for 5 min (or whatever) or until some_obj is Pulse'd
{
//Got Pulse
}
else
{
//Timeout expired
}
}
//And in Stop()...
_exit = true;
lock(some_obj)
{
Monitor.Pulse(some_obj); //Wakeup the thread in Run() if it's currently Wait'ing
}
yeah that's cool, you can also call Thread.Interrupt() to interrupt the sleep, rather than waiting for sleep to return normally.
in the case the thread is not blocking when you interrupt it, it will continue processing normally until it tries to sleep again.
Is there a reason you couldn't just use a timer inside the thread? You'd get what you want, a thread that stays alive forever while firing off your method, plus you could just stop the timer at any point without waiting for 5 minutes or interrupting threads?
(I'm not very experienced in threading, so I might be missing something obvious?)
If time interval is critical then prefer high resolution timers provided in windows which will trigger with higher accuracy.
Seems like a good solution to me. If you're worried about stopping sooner, you can set the sleep time to be less and keep a count so you only run the actual code every 5 minutes. That way it's checking the boolean more often and can break out sooner.
You could look into System.Timers.Timer as well, though truthfully just sleeping is not a bad solution.