I'm starting a Thread that runs routine tasks with some Files, unfortunately, calling Thread.Sleep inside that thread callback hangs up Windows for the specified time, ie. my cursor freezes and CTRL+ALT+DEL does nothing either. How do I specifically "Sleep" the background thread without hanging up the UI?
I'm creating the thread using this:
createThread = new Thread(new ThreadStart(this.createFileExec));
createThread.Start();
And my callback is like this:
private void createFileExec() {
....
Thread.Sleep(100);
....
}
How do I specifically "Sleep" the background thread without hanging up the UI?
That's exactly what you are doing by calling Thread.Sleep on your new thread. Are you sure you aren't calling createFileExec from the main thread?
James is right, there is no reason for the UI to hang .
A quick hack that you can try is to use loops instead of Thread.Sleep .
for (int i = 1; i <= 10000; i++)
{
Console.WriteLine("."); //To know that the thread is asleep.
}
Related
This question already has answers here:
When does a multithreaded console application exit?
(2 answers)
Closed last year.
Sorry if my question seems naive. I'm new to C# and .Net, and still wrap my head around them.
I come from a Go-Lang background, and try to learn C#/.Net multithreading.
In Go the main thread will run and complete its logic regardless of other threads if no wait is used.
I thought it should be the same in C#, however, the code below allow all threads to run completely.
Which means Main thread waits other threads to complete, without using join() or any other wait techniques.
Could you please, let me know what I missed here or misunderstood.
namespace TestThread
{
internal class Program
{
static void Main(string[] args)
{
Thread T1 = new Thread(PrintY);
T1.Start();
// The following is the funtion of the Main thread.
for (int i = 0; i < 10; i++) Console.Write("x");
}
static void PrintY()
{
for (int i = 0; i < 100; i++)
{
Console.Write("Y");
Thread.Sleep(100);
}
}
}
}
The output is like the following:
xxxxxxxxxYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
I expected at most one Y in the results before the Main method finishes and therefore the process terminates. What is keeping the process alive when the main thread is completed?
When you are creating Thread via constructor by default it's Thread.IsBackground is set to false:
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.
And:
By default, the following threads execute in the foreground (that is, their IsBackground property returns false):
The primary thread (or main application thread).
All threads created by calling a Thread class constructor.
So it will prevent the app from terminating. If you want your threads to allow the application to terminate you can set this property to false:
Thread T1 = new Thread(PrintY);
T1.IsBackground = true;
...
Also note that manually creating threads is rarely needed operation in modern C#. After introduction of Task Parallel Library (TPL) usually Task APIs are used instead of directly manipulating the threads (_ = Task.Run(PrintY); for example can be used in this case).
I have a little c# app with multiple threads runing, but my main thread has to wait for all of threads to finish then it can do the rest.
problem now is that im using .join() for each thread, this seems wait for each thread to finish then it goes to next thread, which makes app not really multi-threading and take long time to finish.
so I wonder if there is any way I can get around this problem or just a way to check if there are no more threads is active.
thanks
If you're hanging on to the Thread object, you can use Thread.IsAlive.
Alternately, you might want to consider firing an event from your thread when it is done.
Thread.Join() doesn't mean your application isn't multithreaded - it tells the current thread to wait for the other thread to finish, which is exactly what you want.
Doing the following:
List<Thread> threads = new List<Thread>();
/** create each thread, Start() it, and add it to the list **/
foreach (Thread thread in threads)
{
thread.Join()
}
will continue to run the other threads, except the current/main thread (it will wait until the other threads are done).
Just use Thread.Join()
Ye, as said by Cuong Le, using Task Parallel Library would be much efficient.
However, you can Create a list of Threads and then check if they are alive or not.
var threadsList = new List<Thread>();
threadsList.Add(myThread); // to add
bool areDone = true;
foreach (Thread t in threadsList) {
if (t.IsAlive)
{
areDone = false;
break;
}
}
if (areDone)
{
// Everything is finished :O
}
Run multiple at same time but wanted to wait for all of them to finish, here's a way of doing the same with Parallel.ForEach:
var arrStr = new string[] {"1st", "2nd", "3rd"};
Parallel.ForEach<string>(arrStr, str =>
{
DoSomething(str); // your custom method you wanted to use
Debug.Print("Finished task for: " + str);
});
Debug.Print("All tasks finished");
That was the most simplest and efficient i guess it can go if in C# 4.0 if you want all tasks to run through same method
Try using BackgroundWorker
It raises an event in the main thread (RunWorkerCompleted) after its work is done
Here is one sample from previously answered question
https://stackoverflow.com/a/5551376/148697
I'm building an app using TPL in VS2010 Ultimate. The most of the times I run the app it becomes unresponsive when I Call DoRepresentation() from the UI's thread.
void DoRepresentation()
{
Parallel.ForEach(cgs, loopOptions, g =>
{
UpdateRepresentation(g);
});
}
void UpdateRepresentation(object g)
{
view.Invoke(new Action(() =>
{
representation = new MyRepresentation(g);
}));
}
I don't know why the app is becoming unresponsive. Am I having a deadlock?
Inside MyRepresentation I do some calls to OpenGL.
view is a Control inside Form1 (the main form).
When the app become unresponsive I pause it from the VS IDE and here's the info I get
In the "Parallel Tasks" window I get the following:
ID Status Message<br>
1 ?Waiting Task1 is waiting on object: "Task2"<br>
2 ?Waiting No waiting information available<br>
In the "Call Stack" window I get the following:
[In a Sleep, wait, or join]<br>
[External Code]<br>
Test.dll!Render.DoRepresentation()<br>
App1.exe!Form1.Button1_Click<br>
Any help will be appreciated.
Yes, you are having a deadlock. What Parallel.ForEach() does is that it runs the iterations using one or more threads including the current one and then blocks the current thread until all iterations are complete.
This means that if you call DoRepresentation() from the UI thread, you get a deadlock: the UI thread is waiting for iterations on other threads to finish, while those other threads are waiting for Invoke() to finish, which can't happen if the UI thread is blocked.
Also, in your case, using Parallel.ForEach() doesn't make any sense (assuming this is your actual code): you run new MyRepresentation() on the UI thread.
I don't understand what exactly is the code doing (it seems it overwrites representation in each iteration), but I think you should run ForEach() from a background thread. This means DoRepresentation() will return before it finishes its work and so Invoke() will work correctly.
In general, it's not a good idea to block the UI thread for a long time, so you should run any time-consuming code on another thread.
you can use the BeginInvoke insteed of Invoke Method. if you still need then you can lock an object and make sure that this will not be accessible from the other thread until its realized.
using the Begin Invoke Method
void UpdateRepresentation(object g)
{
view.BeginInvoke( new Action(() =>
{
representation = new MyRepresentation(g);
}));
}
Using the Lock
void UpdateRepresentation(object g)
{
lock(this)
{
view.Invoke(new Action(() =>
{
representation = new MyRepresentation(g);
}));
}
}
This comment applies to my specific app, which is a Windows app in C#: Using a Lock did not work for me either, and the application just froze up.
BeginInvoke worked, but I didn't like the effect of having UI controls being updated asynchronously.
I ended up starting the main process as a separate thread (System.Threading.Tasks.Task), which would start and instantly give me back control of the main thread. Afterwards, while waiting for several other tasks to end execution in a loop, I also ended up having to insert this line: System.Windows.Forms.Application.DoEvents() to enable the system to process all messages waiting in the queue. Now it works right for my application. There might be another way to skin this cat, but it works now.
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.
I am having a problem, for which I am not able to find a solution. The problem is as follows:
In the main thread (the default thread), I am starting a thread and then immediately in the main thread, I wait for the thread's exit by calling Thread.Join on the spawned thread. When I do that if the spawned thread tries to callback in the main thread's context by calling Dispatcher.Invoke, it hangs. Any ideas how I can allow the callback?
The callback has the logic to signal the thread to exit. Without executing the callback, the thread will never exit, and so the main thread is also stuck.
What's the point of starting a new thread if you just wait for it to complete ? Just do the work on the main thread...
I'm not exactly sure what you are asking but you may try BeginInvoke instead of Invoke
If you're only going to be waiting on the thread to terminate, you could simply have a polling loop, like this:
// var otherThread = ...;
volatile bool terminate = false;
while (!terminate)
{
Thread.Sleep(100);
}
otherThread.Join();
Then, leave it up to the callbacks to set the terminate flag to true once you're ready to join.
I had a similar problem which I finally solved in this way:
do{
// Force the dispatcher to run the queued operations
Dispatcher.CurrentDispatcher.Invoke(delegate { }, DispatcherPriority.ContextIdle);
}while(!otherthread.Join(1));
This produces a Join that doesn't block because of GUI-operations on the other thread.
The main trick here is the blocking Invoke with an empty delegate (no-operation), but with a priority setting that is less than all other items in the queue. That forces the dispatcher to work through the entire queue. (The default priority is DispatcherPriority.Normal = 9, so my DispatcherPriority.ContextIdle = 3 is well under.)
The Join() call uses a 1 ms time out, and re-empties the dispatcher queue as long as the join isn't successful.