I was reading and article about optimizing .Net app performance. The authors state
it shows what the main thread did during all those GCs. Most of the time (97.3%) it was Waiting. This means that GC took place on some other thread (obviously on the FileProcessing thread) and the main thread had to wait until the GCs were finished.
As far as I know .Net GC is stop-the-world collector. Thus, if your Main thread is waiting, that means ALL other threads must be waiting as well. Except GC thread itself.
Is the article outdated or I'm getting it wrong?
The reason is misunderstanding between Background GC which happens in a separate thread and Blocking GC which runs on the same thread as the one who triggered GC.
https://jetbrains.com/help/profiler/CLR_Activity.html
Related
I have a program in which even though the call stack has been processed fully it shows <Not Available> (like this). So I started debugging froze all other threads and ran the thread completely to find out that with an empty call stack it remained there and showed <Not Available> in the thread window of Visual Studio.
So my first question, what exactly is the lifetime of a managed thread (not thread object which is processed by Garbage Collection)?
My second question is how can I get this thread to be destroyed (AKA to garbage collection for objects). Tried GC.collect(), but apparently the garbage collector doesn't process CLR implemented managed threads.
Note I have gone through
Thread Object Lifetime( <- Thread Object, not thread), and
Killing Thread ( <- Killing or terminating a running thread, I am interested for an already finished thread, with an empty call stack), and a number of similar others...
Thanks !!
This is with regard to normal threads and not worker threads taken from the threadpool.
Update- I added a thread sleep to main thread and then added a breakpoint after that to find that the threads had been destroyed now.... I want to know how this is working.
I have a method void DoWork(object input) that takes roughly 5 seconds to complete. I have read that Thread is better suited than ThreadPool for these longer operations but I have encountered a problem.
I click a button which calls threadRun.Start(input) which runs and completes fine. I click the button again and receive the following exception:
Thread is running or terminated; it cannot restart.
Can you not "reuse" a Thread? Should I use ThreadPool? Why is Thread "better suited for longer operations" compared to ThreadPool? If you can't reuse a thread, why use it at all (i.e. what advantages does it offer)?
Can you not "reuse" a Thread?
You can. But you have to code the thread not to terminate but to instead wait for more work. That's what a thread pool does.
Should I use ThreadPool?
If you want to re-use a thread, yes.
Why is Thread "better suited for longer operations" compared to ThreadPool?
Imagine a thread pool that is serving a large number of quick operations. You don't want to have too many threads, because the computer can only do so many things at a time. Each long operation you make the thread pool do ties up a thread from the pool. So the pool either has to have lots of extra threads or may run short of threads. Neither leads to an efficient thread pool design.
For longer operations, the overhead of creating and destroying a thread is very small in comparison to the cost of the operation. So the normal downside of using a thread just for the operation doesn't apply.
If you can't reuse a thread, why use it at all (i.e. what advantages does it offer)?
I'm assuming you mean using a thread dedicated to a job that then terminates over using a thread pool. The advantage is that the number of threads will always equal the number of jobs this way. This means you have to create a thread every time you start a job and destroy a thread every time you finish one, but you never have extra threads nor do you ever run short on threads. (This can be a good thing with I/O bound threads but can be a bad thing if most threads are CPU bound most of the time.)
Thread.Start documentation says:
Once the thread terminates, it cannot be restarted with another call
to Start.
Threads are not reusable. I have already faced this problem a while ago, the solution was to create a new Thread instance whenever needed.
It looks like this by by design.
I encountered the same problem and the only solution I could find was to recreate the thread. In my case I wasn't restarting the thread very often so I didn't look any further.
A search now has turned up this thread on social.msdn where the accepted answer states:
a stopped or aborted thread cannot be stated again.
The MSDN repeat this as well:
trying to restart an aborted thread by calling Start on a thread that has terminated throws a ThreadStateException.
As the message states, you cannot restart the thread. You can simply create a new thread for your next operation. Or, you might consider a design where the background thread keeps working until it completes all of your tasks, rather than launch a new thread for each one.
for(;;){} or while(true){} are useful constructs to 'reuse' a thread. Typically, the thread waits on some synchronization object at the top of these loops. In your example, you could wait on an event or semaphore and signal it from your button OnClick() handler.
It's just in background mode. It sounds like you need to use the ThreadPool because re-starting and re-creating Thread objects are very expensive operations. If you have a long running job that may last longer than your main process, then consider the use of a Windows Service.
I have a thread which blocks itself on some lock.Now For some condition I want to kill the thread in c#.
But the thing is that in thread.abort does not guarantees that it will kill the thread.
If you really want a guarantee of thread death, your best option is to start a new process.
There is an excellent thread that discusses many of the possible pitfalls of thread.abort here.
Assuming you want to kill the thread in a deterministic way when it encounters deadlock . Right ?
Yes thread abort does not guarantee termination but it is almost always a bad idea to use Thread.Abort.
If there was a way to kill the thread instantaneously it can lead to bigger problems . If this thread has taken lock on some resource , is in the middle of some uncommitted transaction etc ,and the thread holding these resource is abruptly killed no other thread can work on these resources.
Best suggestion I can give is is to fix the deadlock issue rather than masking it.
I have developed one window application in C# where i am creating one thread to perform one schedule event. now this application will run the whole day and it will create one thread for each execution of each event. How to remove threads from memory after task assigned to that thread is completed. I dont want to restrict number of threads creation by using thread pool and assigning it a specific count for max thread.
As soon as a thread finishes its execution, it will no longer consume memory and it will be targeted for the garbage collector to collect it. Thus, you don't need to worry about it. However if you are using Task, it is a good practice to Dispose it when it finishes its execution. The Task is IDisposable object.
In this web tutorial on threading in C#, Joseph Albahari writes: "Don't go sleeping in pooled threads!" Why should you not do this? How badly can it affect performance? (It's not that I want to do it; I'm just curious.)
There are only a limited number of threads in the thread pool; thread pools are designed to efficiently execute a large number of short tasks. They rely on each task finishing quickly, so that the thread can return to the pool and be used for the next task.
So sleeping in a thread pool thread starves out the pool, which may eventually run out of available threads, and be unable to process the tasks you assign to it.
The thread pool is meant to quickly do a relatively short task on a different thread without having to spend the cost of creating a new thread. The thread pool has a maximum number of threads, and once that is reached, tasks are queued until a thread becomes available.
A thread sleeping on the thread pool would therefore hold up the queue, or contribute to thread pool exhaustion.
Thread is a heavy-weight object.
Creating a new thread requires lots of resources, such as assigning 1 MB for a managed stack, creating managed thread object, kernel stack, kernel thread object, user thread environment block. This all takes time and memory. Therefore you do not want to create and destroy objects really quickly. Furthermore, once you have more than one thread context switching will take some resources as well
Thread pool is a place where CLR can put unused threads, in case your application needs it. Threadpool initially contains 0 threads, once you request a thread from a pool, the pool will quickly create the minimum number of threads defined for the pool. After around 2 minutes unused threads get killed. But if the load increases and you need more threads, thread pool will slowly create new threads until the maximum bound reached. You cannot have more threads than maximum, all new requests will be queued and executed once a working thread returned to the pool. In worse case scenario you can get OutOfMemoryException
If a thread taken from a pool is blocked, it:
Holds the resources
Does not do any valuable work, while an application may need this thread for a new request
Breaks scalability by introducing blocks