I am creating an application, that is required to do some work in a new thread and save results to static list, then thread dies naturally. There can be only one instance of this additional thread executing at time, so when function responsible for creating thread find thread already working, it should return.
When creating my appliaction i was using this guide on msdn: http://msdn.microsoft.com/en-us/library/7a2f3ay4%28v=vs.80%29.aspx
This guide says:
// Create the thread object. This does not start the thread.
Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork);
// Start the worker thread.
workerThread.Start();
Console.WriteLine("main thread: Starting worker thread...");
// Loop until worker thread activates.
while (!workerThread.IsAlive);
// Put the main thread to sleep for 1 millisecond to
// allow the worker thread to do some work:
Thread.Sleep(1);
So i used this code in my app:
if (TibiaControl.PathFinder.PathFinderThread != null && TibiaControl.PathFinder.PathFinderThread.IsAlive)
return false;
TibiaControl.PathFinder Finder = new TibiaControl.PathFinder(targetX, targetY);
TibiaControl.PathFinder.PathFinderThread = new Thread(new ThreadStart(Finder.FindPath));
TibiaControl.PathFinder.PathFinderThread.Start();
SystemControl.DebugMessage(0, "_findPath -- 1");
while (!TibiaControl.PathFinder.PathFinderThread.IsAlive) ;
Thread.Sleep(1);
SystemControl.DebugMessage(0, "_findPath -- 2");
But when executing this function with high frequency (like once every 20-30ms) it happens that my app gets stuck on
while (!TibiaControl.PathFinder.PathFinderThread.IsAlive) ;
line and main thread gets stuck in an infinite loop (as if thread already have it's work done before an while loop occurs). How can I fix that?
I think you may have blindly copied some code from the example that you don't need:
while (!TibiaControl.PathFinder.PathFinderThread.IsAlive) ;
Thread.Sleep(1);
The reason they did this was to demonstrate the usefulness of their RequestStop method.
I wouldn't use that code as the source for any useful application. First of all, there's much better ways for threads to wait. For example, ManualResetEventSlim. Second, it's hard to tell from the code you've posted whether IsAlive is volatile. Even, then, in an x86 system that really doesn't do anything w.r.t. special code. I would recommend using a safer and more explicit form of thread safe value reading. For example:
while (0 == Interlocked.Read(ref workerThread.IsAlive));
Which means changing creating a new variable IsAlive to as a long. But then, in a single CPU system you've just made the one and only CPU busy with little chance of other threads getting a chance to use it. You should yield control to other threads:
while (0 == Interlocked.Read(ref workerThread.IsAlive)) Thread.Sleep(1);
But, I think starting with that sample code is a bad idea. Try to figure out what you need to do and detail that...
For more information see http://msdn.microsoft.com/en-us/magazine/jj863136.aspx and http://msdn.microsoft.com/en-us/magazine/jj883956.aspx
Combine the IsAlive loop with querying the ThreadState:
while (!myThread.IsAlive
&& myThread.ThreadState != ThreadState.Stopped
&& myThread.ThreadState != ThreadState.Aborted)
{}
This avoids endless loops for the case the thread stops immediately after starting
Related
I wrote this little program:
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(WriteX);
t.Start();
for (int i = 0; i < 1000; i++)
{
Console.Write("O");
}
}
private static void WriteX()
{
for (int i = 0; i < 1000; i++)
{
Console.Write(".");
}
}
}
I ran it about fifty times, and the first character on the console was always "O". It is weird for me, because the t thread starts first then the main continues.
Is there any explanation for this?
This is probably because Thread.Start first causes the change of state of thread on which it is called and OS schedules it for execution whereas the main thread is already running and does not need these two steps. This is probably the reason that the statement in main thread executes first rather the one in the newly created thread. Keep in mind the sequence of thread execution is not guaranteed.
Thread.Start Method
1) Thread.Start Method Causes the operating system to change the state of
the current instance to ThreadState.Running.
2) Once a thread is in the ThreadState.Running state, the operating
system can schedule it for execution. The thread begins executing at
the first line of the method represented by the ThreadStart
Edit It seems to me that representing this in graphical form will make this more clear and understandable. I tried to show the sequence of thread execution in diagram below.
You say:
"It is weird for me, because the t thread starts first then the main continues.".
This is not true. The "main" tread is already running. When t.Start(); is executed, the OS is told t is in the running state. The OS will then schedule execution time for the thread "soon". This is something else than the OS is instructed to stop execution of this thread until thread t is started. In other words, when Start returns, there is no guarantee that the thread has already started executing.
More of an advice than not an answer:
(Please note, that I see no real-life use for what you are trying to achieve, so I treat your problem as a thought experiment/proof of a concept not explained in detail.)
If you want your threads to "race" for control, don't give your main thread a head start! Creating a thread has some overhead and your main thread is already created (since it creates your other thread). If you are looking for a mostly equal chance for both of your main and worker thread, you should wait for your worker thread to be created in the main thread and wait for the main thread to start the race in your background thread. This can be achived by synch objects.
In practice it would look like this:
You should declare two ManualResetEvents which are visible for both your main- and background thread like this:
private static ManualResetEvent backgroundThreadReady = new ManualResetEvent(false);
private static ManualResetEvent startThreadRace = new ManualResetEvent(false);
Then in your main thread, you should wait for your thread being initialized like:
static void Main(string[] args)
{
Thread t = new Thread(WriteX);
t.Start();
backgroundThreadReady.WaitOne(); // wait for background thread to be ready
startThreadRace.Set(); // signal your background thread to start the race
for (int i = 0; i < 1000; i++)
{
Console.Write("O");
}
}
And in your thread:
private static void WriteX()
{
backgroundThreadReady.Set(); // inform your main thread that this thread is ready for the race
startThreadRace.WaitOne(); // wait 'till the main thread starts the race
for (int i = 0; i < 1000; i++)
{
Console.Write(".");
}
}
Please note that I could have used other waitable sync objects (mutex, autoreset event, even a critical section lock with some hack, I've just choose the simplest, fastest solution which can be extended easily).
Your code is non deterministic. Your code contains no thread primitives that would schedule priority of one thread over another or for one thread to wait for another.
Main process continue its next instructions set after invoking the thread ,It will take time to start thread method as light process.
It basically needs time to start the thread up. You are running the thread code at the same time as the rest of the first method. So taking into account the time it takes to start the thread and then get to the point where it is writing the "." does that make sense?
If you have a sort of reset button in your app to start everything again (without exiting) you may find that the first character is the "." because the thread will already exist.
There is only one reason why the main thread will finish before the created thread and that is because it takes time to start a thread. The only time you would use threads to speed up a program is when 2 tasks can be run at the exact same time. If you want to make the second loop finish first , take a look at Parallel.For loops in c#... these will run each loop in the for loop at the same time (not all of them but as much as your PC can handle)
I am exploring threading concept,
Every time when i tried to execute the below code, I am getting different output.
I am starting ThreadOne first, But why is ThreadTwo getting started.
Why am I getting Different output? Can someone explain in Detail?
Thanks In Advance.
static Object newLockobj = new Object();
static void Main(string[] args)
{
Thread tobj1 = new Thread(ThreadOne);
Thread tobj2 = new Thread(ThreadTwo);
tobj1.Start();
tobj2.Start();
Console.ReadLine();
}
static void ThreadOne()
{
Console.WriteLine("Thread One Entered");
lock (newLockobj)
{
Console.WriteLine("Thread 1 started");
Thread.Sleep(2000);
Console.WriteLine("Thread 1 ended");
}
}
static void ThreadTwo()
{
Console.WriteLine("Thread Two Entered");
lock (newLockobj)
{
Console.WriteLine("Thread 2 started");
Thread.Sleep(1000);
Console.WriteLine("Thread 2 ended");
}
}
This is a basic examle for Concurrency. Once you call the .Start() method on a thread object, it starts getting executed independent of the thread that started it. What your programm is doing:
Create the thread objects
Start tobj1 (the thread is not executed directly, but once the scheduler finds a place to put it)
Start tobj2 (the thread is again not executed directly)
The scheduler is responsible to tell the processor which process and which thread to execute. The order in which the threads are started is of no importance.
As soon as one thread starts, he prints the first line ("Thread X Entered"). The Lock is a synchronization statement. Since both threads sync on the same object instance, they cannot enter the Lock block both (Mutual Exclusion). The Lock statement only ensures that the process can work in the critical section without the other process working it his critical section. As you see in your right output, a thread can be interrupted although he is in his critical section ("Thread 2 started", "Thread One Entered", "..."). "Thread One", however, is not allowed to his critical section since the other thread did not release the lock yet.
This is in the heart of threads programming. While you have control over which thread you want to start first, the CPU is not obliged to follow your order of events. During the execution of one thread the CPU is guaranteed to follow you order of code execution as per your programming. When it comes to scheduling different threads, the CPU will follow its own logic and sometimes that logic can seem like random behavior. It will allocate processing time to different threads as it sees fit.
I suggest you read up more on threads programming as not fully understanding this concept and appreciating it's potential pitfalls will lead to many days of hair pulling and possible deadlocks :)
Just google: c# threading. You will get plenty of good resources!
I need to control one thread for my own purposes: calculating, waiting, reporting, etc...
In all other cases I'm using the ThreadPool or TaskEx.
In debugger, when I'm doing Thread.Sleep(), I notice that some parts of the UI are becoming less responsible. Though, without debugger seems to work fine.
The question is: If I'm creating new Thread and Sleep()'ing it, can it affect ThreadPool/Tasks?
EDIT: here are code samples:
One random place in my app:
ThreadPool.QueueUserWorkItem((state) =>
{
LoadImageSource(imageUri, imageSourceRef);
});
Another random place in my app:
var parsedResult = await TaskEx.Run(() => JsonConvert.DeserializeObject<PocoProductItem>(resultString, Constants.JsonSerializerSettings));
My ConcurrentQueue (modified, original is taken from here):
Creation of thread for Queue needs:
public void Process(T request, bool Async = true, bool isRecurssive = false)
{
if (processThread == null || !processThread.IsAlive)
{
processThread = new Thread(ProcessQueue);
processThread.Name = "Process thread # " + Environment.TickCount;
processThread.Start();
}
If one of the Tasks reports some networking problems, i want this thread to wait a bit
if (ProcessRequest(requestToProcess, true))
{
RequestQueue.Dequeue();
}
else
{
DoWhenTaskReturnedFalse();
Thread.Sleep(3000);
}
So, the question one more time: can Thread.Sleep(3000);, called from new Thread(ProcessQueue);, affect ThreadPool or TaskEx.Run() ?
Assuming that the thread you put on sleep was obtained from thread pool then surely it does affect the thread pool. If you explicitly say that the thread should sleep then it cannot be reused by the thread pool during this time. This may cause the thread pool to spawn new threads if there are some jobs awaiting to be scheduled. Creating a new thread is always expensive - threads are system resources.
You can however look at Task.Delay method (along with async and await) that suspends executing code in a more intelligent way - allowing the thread to be reused during waiting.
Refer to this Thread.Sleep vs. Task.Delay article.
Thread.Sleep() affects the thread it's called from, if you're calling Thread.Sleep() in a ThreadPool thread and trying to queue up more it may be hitting the max count of ThreadPool threads and waiting for a thread to finish before executing another.
http://msdn.microsoft.com/en-us/library/system.threading.threadpool.setmaxthreads.aspx
No, the Thread.Sleep() is only on the current thread. Thread.Sleep(int32) documentation:
The number of milliseconds for which the thread is suspended.
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;
}