I'm wondering about one thing - let's assume that the user clicks a button, and the asynch controller's action is invoked. What happens, when the asynchronous action takes e.g. 10 seconds? The user has to wait 10 seconds to view the result of the action? If so, are the asynch controllers really helpful ?
Yes. The user will have to wait 10s for his response -- though, if you have a long running action, you'd like want to invoke it via AJAX from a page rendered via another, shorter action.
The value of the asynchronous controller is that it doesn't block other requests on the same thread while the work is being done. Since you only have a limited number of threads, it is possible that they may all end up being blocked on requests to this action. If that happens, then the server cannot serve any requests. Using an asynchronous controller allows the thread to be returned to the thread pool while the asynchronous operation (wait on network or I/O) completes.
See this discussion on MSDN.
Related
I have a high-priority audio thread that runs periodically and should do minimal synchronization.
Sometimes the main thread needs to ensure that at least one audio cycle has passed and certain parameters have been picked up, before sending the next batch of parameters. For example, when disabling an audio node the main thread needs to wait until the next cycle when the disabling command is picked up and the node shuts itself down.
At times it is important for the main thread to wait until the command is fully executed, but other times it's not important, so nobody might be listening to the sync event. Hence the "lossy" scenario.
So what is the best way of notifying other threads about an event with minimal overhead and possibly in a "lossy" way?
Can't think of ways of using a semaphore for this task. Are there any canonical ways of achieving this? Looks like Java's notifyAll() works precisely this way, if so, what synchronization mechanism is used behind notifyAll()?
Edit: been thinking, is there such a thing as "send me a semaphore in a queue and I'll signal it"? Seems a bit too complicated but theoretically it could do the job. Any simpler tools for the same task?
As a rule, you never want to block the main thread (or, at least, for more than a few milliseconds). If the response might ever take longer than that, rather than actually waiting, we would adopt asynchronous patterns, let the main thread proceed. Sure, if you need to prevent user interaction, we’d do that, but we wouldn't block the main thread.
The key concern is that if an app blocks the main thread for too long, you have a bad UX (where the app appears to freeze) and you risk having your app killed by the watchdog process. I would therefore not advise using semaphores (or any other similar mechanisms) to have the main thread wait for something from your audio engine controller.
So, for example, let’s say the main thread wants to tell the audio engine to pause playback, but you want the UI to “wait” for it to be acknowledged and handled. Instead of actually waiting, we would set up some asynchronous pattern where the main thread notifies the audio engine that it wants it to pause, the audio controller would then notify the main thread when that request has been processed via some callback mechanism (e.g., via delegate protocol pattern, completion handler closure, etc.). If you happen to need to prevent user interaction during the intervening time, then you’d disable controller and use some UIActivityIndicatorView (i.e., a spinner) or something like that, something that would be removed when the completion handler is called.
Now, you used the term “lossy”, but that generally conveys that you don't mind the request getting lost. But I’m assuming that is not really the case. I'm assuming that you don't really want the request to be lost, but rather only that the main thread doesn't care about the response, confident that the audio controller will get to it when it can. In that case, you'd probably still give this sort of request to the audio controller a callback mechanism, but the main thread just wouldn’t avail itself of it.
Now if you have a sequence of commands that you want the audio engine to process in order, then the audio controller might have a private, internal queue for these requests, where you’d configure it to not start subsequent request(s) until the prior ones finished. The main thread shouldn't be worried about whether the required audio cycle has processed. It should just send whatever requests are appropriate and the audio controller should handle them in the desired order/timing.
What is synchronous and asynchronous in ios ? I am new in objective c. Which one i should use in my code while i am getting data from server. So please help me.
Thanks in advance.
You should always use asynchronous loading of network requests.
Asynchronous never block the main thread waiting for a network response.
Asynchronous can be either synchronous on a separate thread, or scheduled in the run loop of any thread.
Synchronous blocks main thread until they complete request.
For Demo code or turorial have a look into this link Asynchronous web service client using NSURLConnection and SBJSON
The majority of the time you will go for asynchronous calls for that kind of operations, otherwise you're UI will block because you are using the main thread.
Synchronous, as the name suggests the action will happen in synchronous with the run loop of your application.
To understand it better, say you have to display some data in UITableview after fetching the data from server.Imagine that the request and response from server takes like 3 seconds. When you are fetching this data synchronously from the server, your app will freeze for like 3 seconds between loading tableview and loading the data contents into that tableview
Now if you are sending your request asynchronously, your app won't freeze but it will load the tableview and tableview contents before the server can respond. In other words, your app won't wait for the 3 second of server response time.You have to take necessary delegate actions or blocks actions to check the response and reload the tabledata so that the server response is displayed in tableview.
Which method is better is pure choice what the developer wants and their app should behave but Apple documentation recommends if you are using synchronous calls do not initiate the call from current run loop.
Using asynchronous all threads are execute the operations parallel. So, Never block the main thread waiting for a network response.
Using synchronous all threads are execute the operations one by one. so, should wait until the other thread task done.
Hope It will be suitable.
Quick note based on other answers: dispatch_sync will not block the main thread unless you dispatch to the main thread.
Example:
// Block main thread because the main queue is on it.
dispatch_sync(dispatch_get_main_queue(), ^{ /*do stuff*/ });
// Block background thread.
dispatch_sync(my_work_queue, ^{ /*do stuff*/ });
A Synchronous call(blocking) is one that has to be completed before subsequent calls can be run in the same queue. It is given all of the processor time for that queue until it is complete. This makes it block the queue.
Asynchronous calls can be started in a queue, and then left running on another thread(processor time schedule), owned by that queue, while other calls are started with other threads.
It is very important to use dispatch_async for web calls because it may take time to get a result back and you want other tasks to be able to start in the queue and use it's threads. A common practice is to do web work, like downloading a file, on a custom background queue and then dispatch to the main queue when it is complete, to update the user.
There is more to this and you can read about dispatch queues from Apple, here.
Currently i am following thread to check wheather my internet is active or not in my application, but as it is taking time to give the response ,so this will freeze my UI.
So is there any way to implement it without freezing UI(like NSOperation).
If the internet is indeed down, it takes time. It is limitation of Apple's API. We have to live with it or put a timer to cancel the operation after 30 secs or so. But if a genuine response especially via GPRS takes more than 30 secs, you will be canceling that too if you put timer condition.
Alternatively, you could check for internet status asynchronously and display an ActivityIndicator or similar in the main thread. This means that you create a new thread which will run parallel with your main thread (in your case, the GUI that are freezing).
I want to put an Abort Label or button below...the processing message is shown in ZK. or is there any way to load my custom components instead of the default Processing. message in ZK.
Want will happen if do abort while processing is it ideal to do that, I want to do that anyways as few times my application sleeps while loading
ZK is built on Servlets. When the busy button is shown on the ui awaiting the ajax response then the servlet thread is doing long running work on the server. Perhaps it would be possible to send another thread to interrupt the first thread but really that is high risk as all the servlet threads can end up doing long running work and no new ones will be available to cancel them.
The best solution is that long running work should not be on the servlet thread but handed off to a background thread or message queue. See zk-asynchronous-ui-updates-and-background-processing. In that example the work is offloaded to a java.util.concurrent.ExecutorService which has an API to cancel the work.
Note that cancelling of a working thread uses interruption and it is not guaranteed that code which doing the work will respond to the interrupt properly such that it is actually cancellable. The answers on the thread cancel with executor service outline some of the issues and you should test whether the work you are doing can be interrupted using the API.
Let's say that if I read from www.example.com/number, I get a random number. In my iPhone app, I want to be able to continuously read from that address and display the new number on the screen after each request is finished. Let's also assume that I want this process to start as soon as the view loads. Lastly, as a side-note, I'm using ASIHTTPRequest to simplify the web requests.
Approach 1: In my viewDidLoad method I could synchronously read from the URL in a loop (execution will not continue until I get a response from the HTTP request). Pros: the requests are serial and I have full control to respond to each one. Cons: the UI never gets updated because I never exit the function and give control back to the run time loop. Clearly, this is not a good solution.
Approach 2: In my viewDidLoad method I create a timer which calls a fetchURL function once per second. Pros: each request is in a separate thread, and the UI updates after each request is finished. Cons: the requests are in separate threads, and cannot be controlled well. For example, if there is a connection timeout on the first request, I want to be able to display an error popup, and not have any further requests happen until settings are changed. However, with this approach, if it takes 3 seconds to timeout, two additional requests will have already been started in that time. If I just slow down the timer, then data comes in too slowly when the connection is working well.
It seems like there should be some approach which would merge the benefits of the first two approaches I mentioned. I would like a way that I could decide whether on not to send the next request based on the result of the previous request.
Approach 3: I considered using a timer which fires more quickly (say every .25 seconds), but have the timer's function check a flag to see what to do next. So, if the previous request has finished, it sends a new request (unless there was an error). Otherwise, if the previous request has not finished, the timer's function returns without sending a new request. By firing this timer more quickly, you would get better response time, but the flag would let me get the synchronization I wanted.
It seems like Approach 3 would do what I want, but it also seems a little forced. Does anyone have a suggestion for a better approach to this, or is something like Approach 3 the best way to do it?
You could do this using GCD with less code and using fewer resources. This is how you could do it:
In viewDidLoad call a block asynchronously (using dispatch_async) that does the following:
Load the data with a synchronous call and handle timeouts if it failed.
If successful, inform the main thread to update the UI.
Queue a new block to run after a delay that does the same thing (using dispatch_after).
To call back to the main thread from another thread I can think of these methods:
If you want to update a custom view, you can set setNeedsDisplay from your block
Otherwise, you could queue a block on what's called "main queue", which is a queue running on the main thread. You get this queue by calling dispatch_get_main_queue. and then treat it like any other queue (for example you can add your block by calling dispatch_async).
If you don't want to use blocks you can use the NSObject's performSelectorOnMainThread:withObject:waitUntilDone: method.
See GCD Reference for more details.
That said, you should never keep performing small requests so frequently (unless for specific tasks like fetching game data or something). It will severely reduce battery life by keeping antenna from sleeping.
I believe an NSOperation is what you need. Use the number 1 solution above, but place the code in your NSOperation's main method. Something like this:
The .h file
#interface MyRandomNumberFetcher : NSOperation {
}
#end
The .m file
#implementation MyRandomNumberFetcher
- (void) main {
// This is where you start the web service calls.
}
#end
I'd also recommend adding a reference to the UI controller so your operation queue class can call it back when it's appropriate.
Here's another suggestion. Create an NSOperationQueue that will run your requests on a different thread. If you find you need to refresh the UI call performSelectorOnMainThread. When the request completes create another request and add it to the queue. Set the queue to run only one action at a time.
This way you'll never have two requests running at the same time.