I created the new thread inside main thread
new Thread(() =>
{
// my code
System.Diagnostics.Debug.WriteLine("my code completed");
Application.Current.Dispatcher.Invoke(MyMethod, DispatcherPriority.ContextIdle);
}).Start();
After executing the my code it take 5-8 seconds to call the MyMethod
I saw in the output window that, given bellow line occurs few times before calling the MyMethod
The thread 0x2954 has exited with code 259 (0x103)
To fix this, I tired to Abort the current thread using Thread.CurrentThread.Abort(); but its not solving my problem. I want to call MyMethod immediately after my code completed.
When you create a thread, a lot of processing takes place before your code actually runs. If you need your code to be more responsive, take a look at thread pools (Task are basically the same thing).
Bear in mind that even with a thread pool it can take a little while to start things off, but it should be much less than starting with a brand new thread.
With your code, what you are doing is starting a thread (which might take a long time), then asking your thread to pass control back to the UI thread, which itself might be busy doing other things and not able to run your code until it is free.
Related
I create some threads to do some work using threadpool. Every thread increments finishedThreads variable, so the main thread knows when all the threadpool threads terminate:
// in the main thread
while (finishedThreads < threadsNumber) {
// wait
}
// threads terminated, we can continue
// last line of the threadpool thread
++finishedThreads;
Everything works fine until I create a big amount of threads - over 50. Then the last thread never terminates, so the finishedThreads is still equal threadsNumber-1 and the main thread never continues. I tried to find out why this happens, using debugging, stopping Visual etc. but nothing helped. The thread is not being terminated, although as Visual shows, it does not execute any code. Have you got any ideas on what goes wrong? Thanks in advance.
[EDIT]: That's how I create new threads:
ThreadPool.QueueUserWorkItem(new WaitCallback(myThreadFunc), someData);
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
I suppose this question can be boiled down to "SpinWait vs. Block?", but I figured there may be a more interesting answer as to why nearly every C# threading tutorial suggests the following call:
Thread newThread = new Thread(new ThreadStart(ThreadMethod));
newThread.Start()
while (!newThread.isAlive()) ;
Thread.Sleep(1); // Allow the new thread to do some work
As opposed to blocking like so:
Thread newThread = new Thread(new ThreadStart(ThreadMethod));
newThread.Start()
while (!newThread.isAlive()) Thread.Sleep(1);
Thread.Sleep(1); // Allow the new thread to do some work
My very brute-force testing (surrounding the while loop with calls to DateTime.Ticks) doesn't really reveal anything (says the difference is 0 ticks in both instances).
Is the thread creation process short enough that spinning is more efficient? Or do most tutorials suggest spinning because it's slightly more elegant and the time difference is negligible?
I don't know why you'd use either- off the top of my head, I can't think of any use case for blocking the calling thread until the new thread is alive, since being "Alive" doesn't mean that it has executed anything. If you need to wait for some code to have been run in the new thread before proceeding on the calling thread, you'd want to use a WaitHandle or SpinLock.
You can make the thread set an event when it starts and the main thread to wait on the event. no spinwait no too long sleeping.
This an article explains the use of SpinWait and also mentions different types of Sleep http://www.emadomara.com/2011/08/spinwait-and-lock-free-code.html
what is the problem in the code part below? Any ideas? I m sending command to my device through serial port. After each command the device will work for this command and then the other command comes for it and continues like this.
in Button Click event
{
function1();
Thread.Sleep(5000);
function2();
Thread.Sleep(5000);
function3();
}
I figured out if i erase second sleep and function3 from the code like below, it does both two function but if i want to continue like this way it does not do the third one.
in Button Click event
{
function1();
Thread.Sleep(5000);
function2();
}
works...
Thank you
You're blocking the UI thread. Don't do that. It means your UI can't update itself. Instead, set a System.Windows.Forms.Timer to fire in 5 seconds with the next function to call. Alternatively, do all of this in a different thread entirely (possibly using Sleep, possibly using another kind of timer to fire on a thread-pool thread) and use Control.Invoke/BeginInvoke to marshall back to the UI thread when you need to update the UI itself.
EDIT: Given your "answer", it seems that blocking the UI thread was only one of the problems - and getting the device to respond properly at all is a bigger problem. You shouldn't just rely on sleeping for a certain amount of time. You should detect when the device has completed the previous command. It's possible that it doesn't give any feedback, but that would be horrifically poor design. If at all possible, investigate how to read feedback from the device as to when it's finished (e.g. reading from the serial port!) and only start the next command when the previous one has finished. Depending on how you receive the feedback, you could use a blocking call on a non-UI thread, or use an asynchronous model to trigger things.
The BackgroundWorker might be a solution to solve the blocking of the UI.
Get rid of the Sleeps If the functions are creating their own threads, give them callback methods that trigger the next function after the first has finished.
As the code is presented there it is nothing wrong with it. It will:
Execute function 1
Sleep 5 seconds
Execute function 2
Sleep 5 seconds
Execute function 3
However since this is on a GUI event it will freeze the application while doing so. Consider spinning off the execution into a thread instead.
In .Net 4.0:
Task.Factory.StartNew(() => sendData());
In all .Net versions:
System.Threading.Thread myThread = new System.Threading.Thread(sendData);
myThread.IsBackground = true;
myThread.Start();
And then you have your sendData method:
private void sendData()
{
function1();
Thread.Sleep(5000);
function2();
Thread.Sleep(5000);
function3();
}
If you really need to do stuff in the GUI thread you can make it more responsive by regularly calling Application.DoEvents();, but this is not a good way of solving it.
Also remember that you can't access the GUI from other threads. See http://kristofverbiest.blogspot.com/2007/02/simple-pattern-to-invoke-gui-from.html for sample code on how to invoke the GUI thread from other threads.
Thank you guys. I solve it. The problem is i did not make thread sleep enough. 5000 ms do not enough for the second command.
I recently tried to use backgroundworker instead of "classic" threads and I'm realizing that it's causing, at least for me, more problems than solutions.
I have a backgroundworker running a synchronous read (in this case from serialPort) and getting blocked around 30 seconds in 1 code line, then cancellationpending isn't the solution. I'm seeing that if the application gets closed at this point (either with the cross button and Application.Exit()) the process keeps zombie forever.
I need a way to force abort or to kill the backgroundworker thread.
I put one together that (i think) does the job. Please let me know if im waaaay off.
Here is a simple exaple of how it works.
var backgroundWorker = new BackgroundWorker(){WorkerSupportsCancellation = true};
backgroundWorker.DoWork += (sender, args) =>
{
var thisWorker = sender as BackgroundWorker;
var _child = new Thread(() =>
{
//..Do Some Code
});
_child .Start();
while (_child.IsAlive)
{
if (thisWorker.CancellationPending)
{
_child.Abort();
args.Cancel = true;
}
Thread.SpinWait(1);
}
};
backgroundWorker.RunWorkerAsync(parameter);
//..Do Something...
backgroundWorker.CancelAsync();
Since the background worker is part of the thread pool, we dont want to abort it. But we can run a thread internally which we can allow an abort to occur on. The backgroundWorker then basically runs until either the child thread is complete or we signal to it to kill the process. The background worker thread can then go back into the read pool. Typically I will wrap this up in a helper class and pass through the delegate method that I want the background thread to run passed in as the parameter and run that in the child thread.
Please someone let me know if im banging my head against a wall but it seems to work fine.. But thats the problem with threads isnt it.. the varying results you can get when you run it at different times.
The process should not become a zombie, since the BackgroundWorker thread is marked as "background" and should end when the UI is closed.
I'm not very sure on what you're trying to accomplish, but maybe the SerialPort.DataReceived event is a better solution?
If you're already proficient with the usage of threads, I don't see the point in using BackgroundWorker. It's designed for people who don't understand threads in the first place.
Besides, I don't like the idea of aborting a thread. It feels dangerous, and multithreaded applications don't need any more risk taking.
I don't think the BackgroundWorker supports killing of the thread. Cancelling an operation must be done in the method that performs the job. In your case I think a regular thread will be the best option.
You can try this:
backgroundworker.Dispose();
backgroundworker = null;
GC.Collect(); //this helps cleans up ram