when I quit my application, how to ensure ongoing threads are not interrupted at a bad moment? - vb.net

I'm new to threading, so there are a few things I'm trying to grasp correctly.
I have a windows form application that uses threading to keep my UI responsive while some server shenanigans are going on.
My question is: when I quit my application, what happens to ongoing threads? Will they run to completion or will the abruptly be interrupted?
If they are interrupted, what can I do to make sure they at least don't get interrupted in such a way that would corrupt data on my server (force them to run to a safe place in the code where I know it's ok to interrupt the execution)

You will want to keep a reference of said threads, and call .Abort() on them when you want to terminate. Then you put your thread's code in a try/catch block and handle ThreadAbortException's. This will let you clean up what you are doing and terminate the thread cleanly at your own pace. In the main thread, after you called .Abort(), you just wait until the thread is no longer running (by polling the .IsAlive property of the Thread object) and close your application afterwards.

A thread needs a process to run in. The process won't be able to terminate if you don't terminate all the non-background threads you have started. Threads marked as background thread will be aborted.
So, the behavior is entirely up to your implementation. If you want to close the application, you could wait for all threads to terminate by themself, you could set an event to ask them to terminate and wait or you could just kill the threads.
The UI thread will terminate by itself because it runs a messageloop that stops when requested by the operating system, also see wikipedia and this answer.

Related

Wait until all background jobs have terminated, C

I know how waitpid(-1...) allows me to wait until all children have finished, such as waitpid(-1, &status). But how can I wait until all background processes are finished? Someone suggested that I can use the same waitpid (in a loop?) to achieve this but I don't see how.
To be clear, I'm implementing a shell, and need to add a new built-in command wait, which waits until all background jobs have terminated before returning to the prompt.
I read somewhere else on SO that "You will also want to call waitpid() with the WNOHANG option regularly - say, immediately before you display the shell prompt. This will allow you to detect when the background process has exited or stopped " But again, child != background. So even that I don't believe.
Edit:
I ended up just doing while(wait(NULL) > 0); and that's it, it worked. But what I'm still confused about is don't I WANT to make a distinction between foreground and background because the wait I'm implementing only waits for the background processes, and all children are equal in the eye of wait() or waitpid().
So again, the children I'm waiting for by using wait() or waitpid() aren't necessarily background processes. Am I wrong?
Since you ask in the context of implementing a shell, and evidently your shell supports enough job control to have a concept of background processes, it is reasonable to suppose that your implementation will have a table in which it tracks background jobs. That table can and should track the PID of the process associated with each job.
Having those PIDs in hand, you can waitpid() for specific background jobs until there are no more in the table, or you can waitpid(-1) to collect
any and every job, in a loop, until there are no more background jobs in the table.
If you want to implement background process (and job control) and catch their termination (at least) you must set a signal handler for SIGCHLD, and call wait(-1) inside it. This will let your shell receive asynchronous notifications of background processes termination. You may have a look at Catching SIGCHLD for example and discussion about this.

performSelector:OnThread:waitUntilDone not executing the selector all the time

I have an app where the network activity is done in its separate thread (and the network thread continuously gets data from the server and updates the display - the display calls are made back on the main thread). When the user logs out, the main thread calls a disconnect method on the network thread as follows:
[self performSelector:#selector(disconnectWithErrorOnNetworkThread:) onThread:nThread withObject:e waitUntilDone:YES];
This selector gets called most of the time and everything works fine. However, there are times (maybe 2 out of ten times) that this call never returns (in other words the selector never gets executed) and the thread and the app just hang. Anyone know why performSelector is behaving erratically?
Please note that I need to wait until the call gets executed, that's why waitUntilDone is YES, so changing that to NO is not an option for me. Also the network thread has its run loop running (I explicitly start it when the thread is created).
Please also note that due to the continuous nature of the data transfer, I need to explicitly use NSThreads and not GCD or Operations queues.
That'll hang if:
it is attempting to perform a selector on the same thread the method was called from
the call to perform the selector is to a thread from which a synchronous call was made that triggered the perform selector
When your program is hung, have a look at the backtraces of all threads.
Note that when implementing any kind of networking concurrency, it is generally really bad to have synchronous calls from the networking code into the UI layers or onto other threads. The networking thread needs to be very responsive and, thus, just like blocking the main thread is bad, anything that can block the networking thread is a bad, too.
Note also that some APIs with callbacks don't necessarily guarantee which thread the callback will be delivered on. This can lead to intermittent lockups, as described.
Finally, don't do any active polling. Your networking thread should be fully quiescent unless some event arrives. Any kind of looped polling is bad for battery life and responsiveness.

thread does not start until sub is completed VB.NET

I have the following sub in my program:
public sub RunThis()
Me.Hide()
NEWFORM.Show()
Dim t = New Thread(Sub() Me.printToPowerPoint(saveLocation, printlist))
t.SetApartmentState(ApartmentState.STA)
t.IsBackground = True
t.Start()
While t.isAlive
end while
NEWFORM.close()
Me.Close()
end sub
Running this my program hangs. Does anyone have a solution for this problem.
I am new to threading.
As you probably know, in WinForm projects, the UI can only be dealt with from a single thread. This is affectionately known as the UI thread. That's why, any time you need to access or modify a UI element, you must call the control or form's Invoke method. The Invoke method causes the given delegate to be run on the UI thread. However, doing so will not interrupt any processing that is already being performed by the UI thread. If the UI thread is currently busy, when you call Invoke, it will hang until the UI thread is no longer busy, then it will execute the given delegate.
So, in your code, you are starting a new thread which inside it is trying to invoke a method back on the UI thread. However, immediately after starting the new thread, you then enter a loop which keeps the UI thread busy until the other thread is done. So, when your new thread invokes back to the UI thread, the UI thread is busy and both threads are effectively hung forever.
DoEvents is a keyword you can call from within a lengthy process or loop in the UI thread to signal that you want to, essentially, pause your current processing thereby freeing up the UI thread to process any waiting window messages (painting events, click events, invoke requests, etc.). As soon as all those pending window messages are processed, it will return to doing whatever the next statement is after you called DoEvents. Therefore, if calling DoEvents inside the loop causes it to work properly, that means that your new thread must be invoking back onto the UI thread, or waiting for some other window message to be processed before continuing.
Calling DoEvents is dangerous and widely panned as being bad practice. Typically, if you need to call DoEvents, it's a sign that you need to rethink your design. Usually there is a better way to do what you are doing.
In your case, it looks like starting the new thread is utterly pointless. Unless you have abbreviated you code, it appears that as soon as you start the new thread, you simply put the UI thread on hold waiting for the other thread to finish. If that's the case, it would make much more sense to simply do the work on the UI thread itself rather than starting a new one. In the code you provided, no two threads will ever be effectively be doing processing at the same time, so it's no better than a single thread.

Cancel thread with read() operation on serial port

in my Cocoa project, I communicate with a device connected to a serial port. Now, I am waiting for the serial device to send a particular message of some bytes. For the read operation (and the reaction for once the desired message has been received), I created a new thread. On user request, I want to be able to cancel the thread.
As Apple suggests in the docs, I added a flag to the thread dictionary, periodically check if the flag has been set and if so, call [NSThread exit]. This works fine.
Now, the thread may be stuck waiting for the serial device to finally send the 12 byte message. The read call looks like this:
numBytes = read(fileDescriptor, buffer, 12);
Once the thread starts reading from the device, but no data comes in, I can set the flag to tell the thread to finish, but the thread is not going to read the flag unless it finally received at least 12 bytes of data and continues processing.
Is there a way to kill a thread that currently performs a read operation on a serial device?
Edit for clarification:
I do not insist in creating a separate thread for the I/O operations with the serial device. If there is a way to encapsulate the operations such that I am able to "kill" them if the user presses a cancel button, I am perfectly happy.
I am developing a Cocoa application for desktop Mac OS X, so no restrictions regarding mobile devices and their capabilities apply.
A workaround would be to make the read function return immediately if there are no bytes to read. How can I do this?
Use select or poll with a timeout to detect when the descriptor is ready for reading.
Set the timeout to (say) half a second and call it in a loop while checking to see if your thread should exit.
Asynchronous thread cancellation is almost always a bad idea. Try to stick with event-driven interfaces (and, if necessary, timeouts).
This is exactly what the pthread_cancel interface was designed for. You'll want to wrap the block with read in pthread_cleanup_push and pthread_cleanup_pop in order that you can safely clean up if the thread is cancelled, and also disable cancellation (with pthread_setcancelstate) in other code that runs in this thread that you don't want to be cancellable. This can be a pain if proper cleanup would involve multiple call frames; it essentially forces you to use pthread_cleanup_push at every call level and structure your thread code like C++ or Java with try/catch style exception handling.
An alternative approach would be to install a signal handler for an otherwise-unused signal (like SIGUSR1 or one of the realtime signals) without the SA_RESTART flag, so that it interrupts syscalls with EINTR. The signal handler itself can be a complete no-op; the only purpose of it is to interrupt things. Then you can use pthread_kill to interrupt the read (or any other syscall) in a particular thread. This has the advantage that you don't have to switch your code to using C++/Java-type idioms. You can handle the EINTR error by checking a flag (indicating whether the thread was requested to abort) and resume the read if the flag is not set, or return an error code that causes the caller to clean up and eventually pthread_exit.
If you do use interrupting signal handlers, make sure all your syscalls that can return EINTR are wrapped in loops that retry (or check the abort flag and optionally retry) on EINTR. Otherwise things can break badly.

Make Thread sleep first before it runs

How can I make my thread sleep first before it runs? I know how to get sleep to work, however, whenever my program is run, the thread immediately runs. I want it to WAIT once it is first created to start running. (I am using handlers)
You cannot control when threads are scheduled. If you want it to go to sleep, have the first statement in the thread subroutine do a wait on a condition or something like that and when you are ready you can broadcast to that condition. In pseudo-code:
get-lock
if (we-are-still-supposed-to-sleep)
pthread_cond_wait()
release-lock
I suppose you could have the parent hold the lock while creating the children and then all they have to do is:
get-lock
release-lock
and avoid the condition thing.
What OS? Windoze allows you to create threads in a suspended state. When you have loaded up the thread fields in the ctor, you can resume the thread. Failing that, pass some synchro object in the thread start parameter for the new thread to wait on.
Rgds,
Martin.