NSURLSession dataTaskWithURL - multithreading

I am using NSURLSession dataTaskWithURL:completionHandler. It looks like completionHandler is executed in a thread which is different than the thread(in my case, it's the main thread) which calls dataTaskWithURL. So my question is, since it is asynchronized, is it possible that the main thread exit, but the completionHandler thread is still running since the response has not come back, which is the case I am trying to avoid. If this could happen, how should I solve the problem? BTW, I am building this as a framework, not an application.Thanks.

In the first part of your question you seem un-sure that the completion handler is running on a different thread. To confirm this let's look at the NSURLSession Class Reference. If we look at the "Creating a Session" section we can see in the description for the following method the answer.
+ sessionWithConfiguration:delegate:delegateQueue:
Swift
init(configuration configuration: NSURLSessionConfiguration,
delegate delegate: NSURLSessionDelegate?,
delegateQueue queue: NSOperationQueue?)
Objective-C
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration
delegate:(id<NSURLSessionDelegate>)delegate
delegateQueue:(NSOperationQueue *)queue
In the parameters table for the NSOperationQueue queue parameter is the following quote.
An operation queue for scheduling the delegate calls and completion handlers. The queue need not be a serial queue. If nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls.
So we can see the default behavior is to provide a queue whether from the developer or as the default class behavior. Again we can see this in the comments for the method + sessionWithConfiguration:
Discussion
Calling this method is equivalent to calling
sessionWithConfiguration:delegate:delegateQueue: with a nil delegate
and queue.
If you would like a more information you should read Apple's Concurrency Programming Guide. This is also useful in understanding Apple's approach to threading in general.
So the completion handler from - dataTaskWithURL:completionHandler: is running on a different queue, with queues normally providing their own thread(s). This leads the main component of your question. Can the main thread exit, while the completion handler is still running?
The concise answer is no, but why?
To answer this answer this we again turn to Apple's documentation, to a document that everyone should read early in their app developer career!
The App Programming Guide
The Main Run Loop
An app’s main run loop processes all user-related events. The
UIApplication object sets up the main run loop at launch time and uses
it to process events and handle updates to view-based interfaces. As
the name suggests, the main run loop executes on the app’s main
thread. This behavior ensures that user-related events are processed
serially in the order in which they were received.
All of the user interact happens on the main thread - no main thread, no main run loop, no app! So the possible condition you question mentions should never exist!
Apple seems more concerned with you doing background work on the main thread. Checkout the section "Move Work off the Main Thread"...
Be sure to limit the type of work you do on the main thread of your
app. The main thread is where your app handles touch events and other
user input. To ensure that your app is always responsive to the user,
you should never use the main thread to perform long-running or
potentially unbounded tasks, such as tasks that access the network.
Instead, you should always move those tasks onto background threads.
The preferred way to do so is to use Grand Central Dispatch (GCD) or
NSOperation objects to perform tasks asynchronously.
I know this answer is long winded, but I felt the need to offer insight and detail in answering your question - "the why" is just as important and it was good review :)

NSURLSessionTasks always run in background by default that's why we have completion handler which can be used when we get response from Web service.
If you don't get any response explore your request URL and whether HTTPHeaderFields are set properly.
Paste your code so that we can help it

I just asked the same question. Then figured out the answer. The thread of the completion handler is setup in the init of the NSURLSession.
From the documentation:
init(configuration configuration: NSURLSessionConfiguration,
delegate delegate: NSURLSessionDelegate?,
delegateQueue queue: NSOperationQueue?)`
queue - A queue for scheduling the delegate calls and completion handlers. If nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls.*
My code that sets up for completion on main thread:
var session = NSURLSession(configuration: configuration, delegate:nil, delegateQueue:NSOperationQueue.mainQueue())
(Shown in Swift, Objective-C the same) Maybe post more code if this does not solve.

Related

how to access a worker thread from UI thread?

I have a working thread running all along the runtime, who generates events.
I can handle those events inside the UI thread by using disp = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher.
more precisely, I do the modifications to the UI by using disp->RunAsync(...) anywhere inside the working thread.
but I don't know how to do the inverted operation. I want to have some Async function inside the UI thread to perform operation (on some std::unique_ptr) in the working thread when I click on some button.
If I understand correctly you want to be able to run an async operation when a button is clicked, but on a specific thread to which you refer as your worker thread.
First - Since you want to use a resource in 2 threads you should not use unique_ptr and use shared_ptr since you share this resource between the two threads.
Second - if you don't necessarily have to run the action on a specific thread then you can simply use Windows::System::Threading::ThreadPool::RunAsync and capture the shared_ptr by value.
e.g:
namespace WST = Windows::System::Threading;
WST::ThreadPool::RunAsync(
ref new WST::WorkItemHandler(
[mySharedPtr](Windows::Foundation::IAsyncAction^ operation)
{
mySharedPtr->Foo();
}));
In case you have to run the operation on a specific thread then I assume you want to be able to append operations to an already running thread, otherwise you are creating a thread and you can use the above example.
So in order to append operations to an already running thread, that thread must have the functionality of getting a new operations and then running those operations in a synchronous order. This functionality is basically what the Dispatcher provides. This is what an Event Loop is, also called: message dispatcher, message loop, message pump, or run loop. Also you can find information by reading on the Recator\Proactor design pattern.
This CodeProject page shows one way of implementing the pattern, and you can use Winrt component to make it better \ more conveniant \ more familiar

How to safely use [NSTask waitUntilExit] off the main thread?

I have a multithreaded program that needs to run many executables at once and wait for their results.
I use [nstask waitUntilExit] in an NSOperationQueue that runs it on non-main thread (running NSTask on the main thread is completely out of the question).
My program randomly crashes or runs into assertion failures, and the crash stacks always point to the runloop run by waitUntilExit, which executes various callbacks and handlers, including—IMHO incorrectly—KVO and bindings updating the UI, which causes them to run on non-main thread (It's probably the problem described by Mike Ash)
How can I safely use waitUntilExit?
Is it a problem of waitUntilExit being essentially unusable, or do I need to do something special (apart from explicitly scheduling my callbacks on the main thread) when using KVO and IB bindings to prevent them from being handled on a wrong thread running waitUntilExit?
As Mike Ash points out, you just can't call waitUntilExit on a random runloop. It's convenient, but it doesn't work. You have to include "doesn't work" in your computation of "is this actually convenient?"
You can, however, use terminationHandler in 10.7+. It does not pump the runloop, so shouldn't create this problem. You can recreate waitUntilExit with something along these lines (untested; probably doesn't compile):
dispatch_group group = dispatch_group_create();
dispatch_group_enter(group);
task.terminationHandler = ^{ dispatch_group_leave(group); };
[task launch];
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// If not using ARC:
dispatch_release(group);
Hard to say without general context of what are you doing...
In general you can't update interface from the non main threads. So if you observe some KVO notifications of NSTasks in non main thread and update UI then you are wrong.
In that case you can fix situation by simple
-[NSObject performSelectorOnMainThread:];
or similar when you want to update UI.
But as for me more grace solution:
write separated NSOperationQueue with maxConcurentOperationsCount = 1 (so FIFO queue) and write subclass of NSOperation which will execute NSTask and update UI through delegate methods. In that way you will control amount of executing tasks in application. (or you may stop all of them or else)
But high level solution for your problem I think will be writing privileged helper tool. Using this approach you will get 2 main benefits: your NSTask's will be executes in separated process and you will have root privilegies for executing your tasks.
I hope my answer covers your problem.

InvokeOnMainThread() not necessarily invoking on main thread - bug or feature?

I'm using a Timer and let it perform regular checks. If the test condition is true, I start a thread and let it do what it has to do.
If within that thread I want to change the UI I'm using InvokeOnMainThread(). But as the thread was triggered from a Timer which already is a seprate thread, the InvokeOnMainThread() will invoke things on the Timer's thread and not on the real main thread. I work around it by boxing two InvokeOnMainThread() calls.
Is this working as intended or is it a bug in the Mono framework?
Is the main thread defined as the one who triggered the current thread or is it supposed to return the "root" thread?
NSObject.InvokeOnMainThread is, mostly, a wrapper around performSelectorOnMainThread:withObject:waitUntilDone:
Quote from documentation:
You can use this method to deliver messages to the main thread of your application. The main thread encompasses the application’s main run loop, and is where the NSApplication object receives events.
We can have a deeper look into it (seems weird) if you fill a bug report on http://bugzilla.xamarin.com along with a self-contained test case.

How do I add an event handler for when a thread finishes in MFC?

At the moment, I am using WaitForSingleObject to wait for a sub-task thread to complete. Unfortunately, this causes my GUI to lock up. What I would like to do instead, is set a handler (in the GUI thread) that will be called after the sub-task thread is complete. Is there another function for this?
What you can do is to let the last thing that your thread does be posting a custom message to your window. Then handle that as a regular message using MFC's message map. If you cannot change the thread code, you can create a new thread that waits for your thread and then sends the message.
As you already noticed, it is not a good idea to lock up the GUI thread...
Edit: Posting the message is done using the PostMessage function as pointed out by Hans in the comments.
Could also have a look at MsgWaitForMultipleObjects (or MsgWaitForMultipleObjectsEx).
These allow a thread to wait for event handles and service windows messages (examine the return value to see what causes the call to return). Examples of usage should be available via a goodle search.
http://msdn.microsoft.com/en-us/library/ms684245(VS.85).aspx

Does an asynchronous call always create/call a new thread?

Does asynchronous call always create a new thread?
Example:
If JavaScript is single threaded then how can it do an async postback? Is it actually blocking until it gets a callback? If so, is this really an async call?
This is an interesting question.
Asynchronous programming is a paradigm of programming that is principally single threaded, i.e. "following one thread of continuous execution".
You refer to javascript, so lets discuss that language, in the environment of a web browser. A web browser runs a single thread of javascript execution in each window, it handles events (such as onclick="someFunction()") and network connections (such as xmlhttprequest calls).
<script>
function performRequest() {
xmlhttp.open("GET", "someurl", true);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
alert(xmlhttp.responseText);
}
}
xmlhttp.send(sometext);
}
</script>
<span onclick="performRequest()">perform request</span>
(This is a nonworking example, for demonstration of concepts only).
In order to do everything in an asynchronous manner, the controlling thread has what is known as a 'main loop'. A main loop looks kind of like this:
while (true) {
event = nextEvent(all_event_sources);
handler = findEventHandler(event);
handler(event);
}
It is important to note that this is not a 'busy loop'. This is kind of like a sleeping thread, waiting for activity to occur. Activity could be input from the user (Mouse Movement, a Button Click, Typing), or it could be network activity (The response from the server).
So in the example above,
When the user clicks on the span, a ButtonClicked event would be generated, findEventHandler() would find the onclick event on the span tag, and then that handler would be called with the event.
When the xmlhttp request is created, it is added to the all_event_sources list of event sources.
After the performRequest() function returns, the mainloop is waiting at the nextEvent() step waiting for a response. At this point there is nothing 'blocking' further events from being handled.
The data comes back from the remote server, nextEvent() returns the network event, the event handler is found to be the onreadystatechange() method, that method is called, and an alert() dialog fires up.
It is worth noting that alert() is a blocking dialog. While that dialog is up, no further events can be processed. It's an eccentricity of the javascript model of web pages that we have a readily available method that will block further execution within the context of that page.
The Javascript model is single-threaded. An asynchronous call is not a new thread, but rather interrupts an existing thread. It's analogous to interrupts in a kernel.
Yes it makes sense to have asynchronous calls with a single thread. Here's how to think about it: When you call a function within a single thread, the state for the current method is pushed onto a stack (i.e. local variables). The subroutine is invoked and eventually returns, at which time the original state is popped off the stack.
With an asynchronous callback, the same thing happens! The difference is that the subroutine is invoked by the system, not by the current code invoking a subroutine.
A couple notes about JavaScript in particular:
XMLHttpRequests are non-blocking by default. The send() method returns immediately after the request has been relayed to the underlying network stack. A response from the server will schedule an invocation of your callback on the event loop as discussed by the other excellent answers.
This does not require a new thread. The underlying socket API is selectable, similar to java.nio.channels in Java.
It's possible to construct synchronous XMLHttpRequest objects by passing false as the third parameter to open(). This will cause the send() method to block until a response has been received from the server, thus placing the event loop at the mercy of network latency and potentially hanging the browser until network timeout. This is a Bad Thing™.
Firefox 3.5 will introduce honest-to-god multithreaded JavaScript with the Worker class. The background code runs in a completely separate environment and communicates with the browser window by scheduling callbacks on the event loop.
In many GUI applications, an async call (like Java's invokeLater) merely adds the Runnable object to its GUI thread queue. The GUI thread is already created, and it doesn't create a new thread. But threads aren't even strictly required for an asynchronous system. Take, for example, libevent, which uses select/poll/kqueue, etc. to make non-blocking calls to sockets, which then fires callbacks to your code, completely without threads.
No, but more than one thread will be involved.
An asynchronous call might launch another thread to do the work, or it might post a message into a queue on another, already running thread. The caller continues and the callee calls back once it processes the message.
If you wanted to do a synchronous call in this context, you'd need to post a message and actively wait for the callback to happen.
So in summary: More than one thread will be involved, but it doesn't necessarily create a new thread.
I don't know about javascript, but for instance in the Windows Forms world, asynchronous invocations can be made without multiple threads. This has to do with the way the Windows Message Pump operates. Basically a Windows Forms application sets up a message queue through which Windows places messages notifying it about events. For instance, if you move the mouse, messages will be placed on that queue. The Windows Forms application will be in an endless loop consuming all the messages that are thrown at it. According to what each message contains it will move windows around, repaint them or even invoke user-defined methods, amongst other things. Calls to methods are identified by delegates. When the application finds a delegate instance in the queue, it happily invokes the method referred by the delegate.
So, if you are in a method doing something and want to spawn some asynchronous work without creating a new thread, all you have to do is place a delegate instance into the queue, using the Control.BeginInvoke method. Now, this isn't actually multithreaded, but if you throw very small pieces of work to the queue, it will look like multithreaded. If, on the other hand you give it a time consuming method to execute, the application will freeze until the method is done, which will look like a jammed application, even though it is doing something.

Resources