This is more of an "I'd like to know" kind of question, than a real problem.
While working on improving my threading skills, and I'm running into the following conundrum.
The source code
internal class Program
{
private static void Main(string[] args)
{
var thread = new Thread(() => Print("Hello from t"));
thread.Start();
//thread.Join();
}
private static void Print(string message)
{
Console.WriteLine(message);
}
}
The problem
If I run the application from Visual Studio (regardless of whether it's Debug or Release configuration), the message is never displayed in the Output window unless I wait for the thread to exit (using Join).
The solution
Run the compiled executable from a command prompt, and you see the expected output.
My question
I'm gonna throw a wild guess and say that the Visual Studio environment makes all the difference.
What I'm wondering is, if I were working on a real-world application, how would I use Visual Studio to debug said application, without being forced to modify the source code (to use Join)?
In a real-world application, this code should not appear because of the problem with the app quitting before the thread is completed. If you do have this problem, it usually signals a problem with the code.
If you are making use of a message pump (WinForms) or similar (WPF), the application will run as normal, meaning it won't exit until the user (or the application) breaks the loop by requesting the application exit. In this case, the thread will work until it finishes, or until the program exits. Thread.Join() may need to be called anyway, depending on the scenario.
If you are creating a console application, Thread.Join() should be called at the end of the program to ensure the worker thread completes. An alternative is to start the message pump with System.Windows.Forms.Application.Run(). However, it is not designed for this, and should not be used unless you are interacting with the user.
Another aspect, there are two kinds of threads in C#: foreground threads and background threads. Foreground threads keep running after the main thread has stopped. Background threads are stopped when all foreground threads are completed. The default type is a foreground thread. You can explicitly set a thread to background with the Thread.IsBackground property. Visual Studio apparently monkeys around with the threads to the point that the foreground thread doesn't prevent the application from quitting. Running the program outside of the debugger works fine.
It is still a good idea to be sure all threads terminate before the main thread. Who knows what might happen if you have more advanced code running after Main exits.
The call thread.Start() just starts the subsidiary thread and then returns. Since that's the end of your Main function, the program finishes and its process exits before the subsidiary thread has a chance to print the message.
No mystery, nothing weird about Visual Studio environment, just normal Windows process behaviour.
Related
I am trying to make sure my program is not causing a "thread tree" scenario by continuing timers, and opening new Timers (threads) as they cycle... if that makes sense.
Nevertheless, my main question is exactly as it sounds;
I do know how to, and already have open, the thread view in Visual Studios 2017, but none of the threads opened by Timer elapse events are showing up in the thread view.
I don't imagine it has anything to do with the matter, seeing as Timers are the System.Timers - but this project is built from within Unity3D.
I haven't tested this with a Unity3D application but I expect that threads created by a System.Timers.Timer will show up in the Threads window. After all, they are just background threads created in a particular way. You should be able to verify this very easily: Place a breakpoint in the method that gets called by the timer thread. When hit you will see the thread in the Threads window. Continue and the thread will disappear, based on what you describe.
The .NET Framework defines two types of threads: foreground and background.
By default when we create a thread, it is a foreground thread, but we can change it to a background
All processes have at least one thread of execution, which is usually called the main thread because it is the one that is executed when your program begins.
Is this main thread is back ground or foreground thread.
It is really rather best that you completely dismiss the concept of a "foreground thread". The CLR has no notion of it and does not treat the startup thread of program special in any way. It is just a "normal" thread, no different from any other thread you create with the Thread class. The notion that a "foreground thread" is important because it is doing the most visible and most "important" job is sometimes true but not always. Not in a service or a Modern UI app for example, it is worker thread that does the heavy lifting in them. It is true-ish in a console, Winforms or WPF app.
The concept is only truly valid in legacy runtime environments, like those of a C or C++ program. Their execution model dates from the 1970s, operating systems did not support threads back then. Specific in such legacy runtime environments is that the program always terminates when the startup thread ends, regardless of what other threads are running. This is not the way the CLR works, it thinks those other threads are just as important. Of course they are.
Still thinking of the concept of a "background thread" is okay. A threadpool thread is certainly backgroundish. Their IsBackground property is always true. Something you can change btw, you can simply set it to false and the CLR doesn't treat it like a background thread anymore. But you can't change its ApartmentState, it is always MTA and that makes them fundamentally unsuitable to display any user interface. In other words, you can never see them :)
The most important attribute of a background thread is that you can treat them like little soldiers that you don't mind getting killed in the line of duty. Randomly and without any notification and the expectation of no dire consequences. Pretty important that they do a non-critical job of course. It already gets iffy if, for example, you let such a thread write a file. That's going to leave a half-written file behind when the soldier gets shot. That has a knack of causing trouble later, another program reading that file is going to malfunction. A network or dbase connection is typical for a background thread. The software on the other end of the wire will detect that the connection was lost. It can't otherwise tell the difference between a hard program crash and a normal exit. Tends to end up okay, usually, such software was written to deal with that.
Long story short, only the IsBackground property matters. When a thread exits, the CLR iterates the remaining threads that are still running. If any of them have IsBackground = false then the process keeps running. If not, the CLR will unload the primary AppDomain. Which gets any soldiers shot with a rude abort.
The whole purpose of background threads is that the process will exit if the only threads left executing are background threads.
The main thread needs to be a foreground thread, or the app would just immediately exit.
I have a c# .NET multi-threaded application that is freezing the interface. What is unusual about this is that the interface does not freeze unless I let the system sit idle long enough for the screen saver to start (which requires me to reenter my password to re-gain access to the system). When the interface becomes visible again (after I have successfully entered my password) all the windows are white. I can see the window titles, move the windows around, minimize them and such, but the screens are not repainting. When I break all and enter the debugger, the call stack has Application.Run(), external code, and then "in a sleep, wait, or join". I put break points in all four of the threads I open and they are still running, it is just the main app's UI thread that is blocked. When I look at my thread list, what was my main thread and my four worker threads now consists of my main thread and 11 worker threads. I didn't open this many threads so it must be the serialport class.
Now let me describe my program.
My main app allows users to collect and monitor data from serial ports. I have implemented this in the following way. When a connection is desired, a button is pressed on the main app which calls a function in a DLL which opens a status window and then launches a thread which monitors the serial port. When that function returns, the main app launches a thread to monitor a queue created in the DLL when it is initialized. When data is received from the serial port, the data is parsed and then the status window is updated (via a delegate) and the data is pushed onto the queue. When the main apps worker thread sees data in the queue it retrieves it and posts it in a list box on the main app, using a delegate. In all cases I use BeginInvoke to call these delegates.
My DLL contains two libraries for the two different types of equipment it can communicate with.
This problem occurs when I have a connection to two devices; hence the four worker threads two for each device. The DLL itself is setup as a comm object so I can access it easily from a C++/MFC app and a c# app, both of which utilize it.
I found that if I add code to the thread inside the DLL so it calls Application.DoEvents() every 30 seconds, the interface will be frozen for about 30 seconds and then resume activity like normal. I figure something is blocking the main thread and forcing DoEvents() to fire seems to break the lock, but I have no idea what might be causing this lock. This is not a solution, just something of interest.
I would appreciate any suggestions you might have. Thanks.
I found that if I add code to the thread inside the DLL so it calls Application.DoEvents() every 30 seconds, the interface will be frozen for about 30 seconds and then resume activity like normal. I figure something is blocking the main thread and forcing DoEvents() to fire seems to break the lock, but I have no idea what might be causing this lock. This is not a solution, just something of interest.
I would recommend running your program under the new Visual Studio 2010 Concurrency Profiler. This will show you, at runtime, which threads are blocked, and which objects they are waiting on. Thread contention is explicitly marked and highlighted for you.
You can use this to easily determine what code is causing the deadlock on your UI thread.
Try changing your Thread Start code to Thread.Start() instead of BeginInvoke(). BeginInvoke does not keep threads tryky seperate from your UI, as it and it may be interacting strangely with DoEvents. You can read up on BeginInvoke and how it works here: http://www.codeproject.com/KB/cs/begininvoke.aspx
Also, DoEvents is NEVER necessary in an application, and can cause a lot of unexpected behavior. Use threadding with UI calls wrapped in a Control.Invoke(...) statement. If you're using .NET 3.5+, you can make this easy with delegates that look like this: Invoke((Action)delegate() {*code goes here*});
I have an application running with the thread,if i perform end-task from the task manager
application is quitting but,in process list an instance will be running(i.e if I do end-task 5 times 5 instances of process running). It might be due to thread.
in this case,if I have to kill all process i need to restart the device :-(.
Manually if I exit It works great.How to overcome from this issue?
I am developing application in c#
As elder_george points out, you have a rogue thread that is preventing the app from exiting and you need to ensure that thread exits when your app shuts down. With CF 3.5 you can usually just set the IsBackground property to truw, though that's not always enough. If the thread is blocking in a system call (like an infinite wait like WaitOne) then the thread will not get schedules and still may not terminate.
The best way to prevent this, and a good practice, is to actually write code that signals your worker threads to shut themselves down. This is often done with a reset event or a boolean flag that the thread checks periodically.
void MyThreadProc()
{
// set this event when the app is shutting down
while(!shutdownEvet.WaitOne(0, false))
{
// do my thread stuff
}
}
This mechanism will also work in CF 2.0 (where IsBackground doesn't exist).
Set IsBackground property on your thread to true.
Hey i got solution for this,
when i perform end task from task manager,control will come next to "Application.Run()" method.
There we can call one user defined function, in that we can perform all the necessary task like killing thread, memory clean up etc.. to end the application smoothly.
Thanks to all for your responses.
We have a SmartClient built in C# that stubornly remains open when the PC its running on is being restarted. This halts the restart process unless the user first closes the SmartClient or there is some other manual intervention.
This is causing problems when the infrastructure team remotely installs new software that requires a machine reboot.
Any ideas for getting the SmartClient app to recognize the shutdown/restart event from Windows and gracefully kill itself?
UPDATE:
This is a highly threaded application with multiple gui threads. yes, multiple gui threads. Its really a consolidation of many project that in and of themselves could be standalone applications - all of which are launched and managed from a single exe that centralizes those management methods and keeps track of those threads. I don't believe using background threads is an option.
OK, if you have access to the app, you can handle the SessionEnded event.
...
Microsoft.Win32.SystemEvents.SessionEnded +=new
Microsoft.Win32.SessionEndedEventHandler(shutdownHandler);
...
private void shutdownHandler(object sender, Microsoft.Win32.SessionEndedEventArgs e) {
// Do stuff
}
It must be a thread that continues to run preventing your application to close. If you are using threading an easy fix would be to set it to background.
A thread is either a background thread or a foreground thread. Background threads are identical to foreground threads, except that background threads do not prevent a process from terminating. Once all foreground threads belonging to a process have terminated, the common language runtime ends the process. Any remaining background threads are stopped and do not complete.
http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx
When a user is logging off or Windows is being shut down, WM_QUERYENDSESSION message is sent to all top-level windows. See MSDN documentation here.
The default behavior of a WinForm application in response to this message is to trigger the FormClosing event with CloseReason == WindowsShutDown or others. The event handler though can choose to be stubborn and refuse to shut the app down, thus keeping the system running.
Check FormClosing handlers of your applications. Maybe there is something in there. I've seen this kind of stuff a couple of times.
Or maybe the .Net app is ignoring close or quit messages on purpose?
Background threads was a quick and dirty solution, best solution is to use synchronization objects (ManualResetEvent, Mutex or something else) to stop the other threads;
Or else keep track of all your opened windows and sent WM_CLOSE message when main app closes.
You have to give more information about how do you start those GUI applications. maybe you start one thread for each application and call Application.Run(new Form1()); ?
You may also look into creating a AppDomain for each GUI Application
Normally a .Net app would respond correctly- at least, that's the 'out of the box' behavior. If it's not, there could be a number of things going on. My best guess without knowing anything more about your program is that you have a long-running process going in the main UI thread that's preventing the app from responding to window messages.