I seem to fail to create a foreground task.
my main thread is supppose to call another thread and then exit.
the other thread suppose to run forever
void MainThreadMain()
{
task_main = Task.Factory.StartNew(() => OtherThread()) ;
return;
}
void OtherThread()
{
while(true)
{
TellChuckNorrisJoke();
}
}
how can I ensure task_main will continue running even that Main Thread is dead?
I assumed il do:
task_main.IsBackgorund = false;
but no such option :\
I can make my main thread to wait a signal from my other thread that it passed to Foreground mode. but thats plain silly.
The obvious question is: why don't you run your work on the main thread?
Assuming this is not an option, you should use a Thread not a Task. Then you can set:
Thread.IsBackground = false;
This will prevent your application from terminating while the worker thread is running.
Related
I am using Task to create and perform some operations by a different thread, once the operation is done I also have called back to be called.
System.Threading.Tasks.Task.Factory.StartNew(() =>
this._httpService.CreateRecord(new Uri(Configuration.Current.CreateRecordUrl), httpObj)).ContinueWith(
(response) =>
{
if (!response.IsFaulted)
{
if (httpObj.CallBack != null)
{
httpObj.CallBack(response.Result);
}
}
else {
this._logger.Error("There was some error which causes the task to fail");
}
});
My console application's main thread is not waiting for the Task thread to complete, because it's background thread.
How can I make task thread foreground thread?
Thanks
StartNew() method returns a Task instance. Calling Wait() method on the returned task will block the main thread until the task finishes.
static void Main(string[] args)
{
var task = Task.Factory.StartNew(() =>
{
// ...
});
task.Wait(); // The main application thread waits here until the task returns
}
My console application's main thread is not waiting for the Task thread to complete, because it's background thread.
Your application is not waiting for the task, because you don't tell it to do so.
As others have already stated, use Wait/Result or await to wait for the task, depending on whether you're in an asynchronous context or not.
How can i make task thread foreground thread.
Most likely you don't want to do that in the first place. A background thread is a thread that terminates when all foreground threads have ended. Thread pool threads are inherently background threads, if you actually want to schedule your task to a foreground thread, that is, a thread that will keep the app process alive even if the main thread is finished, you'll have to create your own TaskScheduler. That, btw, would be a reason to use Task.Factory.StartNew. If you don't need Task.Factory.StartNew, go for Task.Run.
You should wait for completion of the Task in your main thread.
Change your code to
var task = System.Threading.Tasks.Task.Factory.StartNew(() =>
this._httpService.CreateRecord(new Uri(Configuration.Current.CreateRecordUrl), httpObj)).ContinueWith(
(response) =>
{
if (!response.IsFaulted)
{
if (httpObj.CallBack != null)
{
httpObj.CallBack(response.Result);
}
}
else {
this._logger.Error("There was some error which causes the task to field");
}
});
task.Wait(); // Wait till your Task has finished.
The Wait() method has some overloads to specify how long to wait. Also you have to add some exception handling if Task execution fails due to an exception of cancellation.
Try creating a fresh new Thread instead of taking from the pool. For eg:
Thread t = new Thread(()=>
{
//all your code goes here
});
t.IsBackground = false; //by default it will be foreground. so don't need this line in your case
t.Start();
This will create a foreground thread for u and it will make sure the thread completes its execution.
As I understand it, if I set _myThread.isBackground = true then the thread should exit when the form is closed. Unfortunately I'm not finding that my thread is exiting. Here is what my code looks like:
private void MainForm_Load(object sender, EventArgs e)
{
// <snip>
daemon = new Daemon();
// <snip>
}
public Daemon()
{
// Start the main thread which will do most of the connection checking and work
_mainThread = new Thread(() => MainThread(this));
_mainThread.IsBackground = true;
_mainThread.Start();
}
/// <summary>
/// This is the work that the main thread does.
/// </summary>
private void MainThread(Daemon daemon)
{
while(true)
{
try
{
// Do things.
Thread.Sleep(2000); // Sleep for a bit to not hammer.
}
catch (Exception e)
{
Logger.Exception(e);
}
}
}
I thought that since the thread is started from the form that setting isBackground=true would force it to close on form exit.
Am I missing or misinterpreting something?
Strictly speaking that the thread is a background thread prevents it from keeping the process alive. The process will stick around for as long as there is at least one non-background thread running. The UI thread is a non-background thread, and by default in a winform application closing the main thread will result in that thread completing.
So now that we have all of this we can see that, often enough, closing the main form will "kill" background processes, but there are any number of things that can stop this.
The main thread ending doesn't necessarily mean the application will end, and the UI thread will terminate. One can adjust the behavior of the application to end under different criteria, or add code to run in Main after the application finishes running.
You can also create additional non-UI threads, and if you do, they'll keep the entire process (and all of the background threads) alive.
According to documentation background thread just wont prevent the process from terminating. There is no guarantee that the thread will finish "nicely", whatever that may mean.
IsBackground = true means that when main thread ended (and all other non-background threads) - it'll stop. But what are these threads ? I believe when you close your mainform you still have one non-background thread running may be one where this form was created and ititialized.
I've got a strange error in my app: I have a single background thread and multiple normal threads. When I close the application, all the normal threads exit eventually, while the background one continues to work.
I've checked in the parallel stacks, and the background thread remains the only one working.
How can I check if the the application is exiting so I can exit the background thread from inside?
If your application has a reference to the background thread, call thread.Abort() method on termination of application.
Depending on used framework there are other options. For example in WPF the background thread may handle Application.Exit event:
new Thread(new ThreadStart(() =>
{
var thread = Thread.CurrentThread;
Dispatcher.Invoke((Action)delegate
{
Exit += (obj, args) => thread.Abort();
});
while (true) ; // background thread is always busy
})).Start();
I have the following multithreaded program:
class Program{
static void main(){
(new Thread(DoSomething)).Start();
}
static void DoSomething(){
// Dome something here...
}
}
A couple of questions:
Does the main thread exit after spinning off the child thread?
If it does exit and the child thread is a background thread: Is the main process going to exit or will it wait for the background thread to finish?
"By default, threads you create explicitly are foreground threads. Foreground threads keep the application alive for as long as any one of them is running, whereas background threads do not. Once all foreground threads finish, the application ends, and any background threads still running abruptly terminate.
class PriorityTest
{
static void Main (string[] args)
{
Thread worker = new Thread ( () => Console.ReadLine() );
if (args.Length > 0) worker.IsBackground = true;
worker.Start();
}
}
If this program is called without any arguments, the worker thread will take foreground status and will wait on the ReadLine statement for the user to press Enter. Simultaniously, the main thread exits, but the application keeps running because a foreground thread is still alive.
However, if an argument is passed to Main(), the worker is assigned background status, and the program exits almost immediately as the main thread ends (terminating the ReadLine and the program)."
See Joseph Albahri's (a genius and great guy) page on threading for more information (it is where this was extracted from).
Typically, if you want to wait for the child thread to complete, you'd add a x.Join(); line (where x is the variable of your thread) wherever you want your main thread to stop and wait for the child to complete.
EDIT: So, yes, the main thread will exit unless one of three cases occurs:
a) the spawned thread completes before the rest of the main thread code (if you add any)
b) You have a condition that waits for the thread to complete (such as the Join statement I mentioned, but there are other ways too).
c) The main thread goes into a semi-infinite loop (such as a game/graphics engine).
In your bare-bones example, it will exit for sure (given your question's parameters, a background thread).
EDIT2: Sorry, I seem to have dodged your second question (and actually only considered background threads the whole while). If it's a background thread it will exit as I've explained, if it's foreground then it shouldn't (though I don't have much experience with foreground threads, so I can't say for sure).
So to answer your questions: Yes, the main thread exits. Yes, if the child is specifically a background thread, the process will exit as well.
EDIT3: Final edit, I promise. I just wanted to add some code so that you could prove the answer yourself (which is always nice to be able to do):
static void Main(string[] args)
{
Thread thready = new Thread(DoSomething);
thready.IsBackground = true;
thready.Start();
}
static void DoSomething()
{
while (true)
{
Console.Write("thread's looping \n");
}
}
By toggling the thready.IsBackground = true; to thready.IsBackground = false; you get a program that runs forever (not exiting until the thread does). Leaving it as true will exit very quickly.
Depends on Thread.IsBackground.
The process will not exit before all the foreground threads finish. In the following example...
class Program {
static void Main(string[] args) {
(new Thread(DoSomething)).Start();
}
static void DoSomething() {
Thread.Sleep(5000);
}
}
...the process will exit after 5 seconds.
But in this example...
class Program {
static void Main(string[] args) {
(new Thread(DoSomething) { IsBackground = true }).Start();
}
static void DoSomething() {
Thread.Sleep(5000);
}
}
...the process will exit (almost) immediately. The effect on the child background thread that is still running is similar to forcibly killing the process, so avoid doing that if possible.
main process thread will definitely exit...
edit: i rechecked the docs and found that IsBackground property is false by default...which means the main thread will wait...the earlier response ws with regards to the 2nd question
I thought I understood this, and am a bit embarrassed to be asking, but, can someone explain to me why the breakpoint in the exception handler of following code is not hit?
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
Thread testThread = new Thread(new ParameterizedThreadStart(TestDownloadThread));
testThread.IsBackground = true;
testThread.Start();
}
static void TestDownloadThread(object parameters)
{
WebClient webClient = new WebClient();
try
{
webClient.DownloadFile("foo", "bar");
}
catch (Exception e)
{
System.Console.WriteLine("Error downloading: " + e.Message);
}
}
You're creating a thread, setting it to be a background thread, and starting it. Your "main" thread is then finishing. Because the new thread is a background thread, it doesn't keep the process alive - so the whole process is finishing before the background thread runs into any problems.
If you write:
testThread.Join();
in your Main method, or don't set the new thread to be a background thread, you should hit the breakpoint.
Your thread is a Background thread (you set it so yourself). This means that when the application completes, the thread will be shut down without being given chance to complete.
Because your main has no further content, it exits immediately and both the application and your thread are terminated.
If you were to add a testThread.Join() call then your thread would complete before the app exited and you'd see the exception caught.
Most likely your background thread isn't started before Main exits - starting a new thread may take a while. Since the additional thread is a background thread it is terminated when Main exits.
For demo purposes, you could have your main method wait - e.g. on user input. This would allow the background thread to start running.
Since the new thread's IsBackground is true, it won't prevent the process from terminating. At the end of Main() the only foreground thread terminates, shutting down the process before the other thread gets that far.
Probably because the main thread is ending before the worker thread. Try adding
Console.ReadKey();
at the end of your Main method.