I building an application which receives DStreams from Twitter, the only way to stop the Streaming context is by stoping the execution. I wonder if there is a way to set a time and terminate the streaming socket without stoping the entire application?
You can use either
awaitTerminationOrTimeout(long)
as mentioned in the previous answer, or you can stop the streaming context manually from your other thread:
// in the main thread
awaitTermination(); // will wait forever or until the context is stopped
// in another thread
streamingContext.stop();
You can use the awaitTermination() method on the streamingContext object to wait for a specified time. Refer this
Related
To begin, I realise I may be causing this problem by addressing a previous problem incorrectly...
In a ViewController main thread I am starting a background thread to get updated data from a server using:
[self performSelectorInBackground:#selector(sampleTask:) withObject:#"CMD" ];
This process can take 15-30 seconds so in the main thread I display a local cache of the data from a SQLite database (populated from a previous request to the server the last time the view was opened) and reload the table once the sync with the server is finished.
If the user navigates back out of this view before the sync with the server is finished, the background thread keeps running until it is done. This itself isn't a problem, until the user changes their mind and goes back into this view again. If the timing is right, there's two background threads trying to sync data with the server. If the user does this a few times, the thread count can build up. Eventually the app will collapse, if not cause other problems on the device.
Is there a way to stop the created threads on a trigger like viewDidDisappear?
Or should I be writing a lock to a shared resource (e.g. NSUserDefaults) to prevent a new background thread from being started?
Or -- like I mentioned in the first line -- do I have a bad approach to the issue of updating the local cache that is just causing further problems like this one?
I think you can use simple bool valued semaphore which shows that some sync task is performing. So before performing the next similar task you should check that semaphore.
If you recreate your viewcontroller each time you need static class variable common for all instances of your view controller.
performSelector:withObject:afterDelay: does not create a separate thread.
To quote part of the docs on that method:
Invokes a method of the receiver on the current thread using the
default mode after a delay
It uses a timer to trigger your selector after a delay. As such it is subject to the same accuracy limitations as NSTimer. (The method performSelectorInBackground:withObject: does submit your selector on a background thread.)
But back to your question.
You can use the method
cancelPreviousPerformRequestsWithTarget:selector:object:
To cancel a pending call to performSelector:withObject:afterDelay:
When using NSURLConnection, you had the option to schedule the connection using NSRunLoop:
- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode
Passing NSDefaultRunLoopMode would effectively cause the connection to pause if the user scrolled, which was great for performance as the user experience was never impacted by the download.
Is there a way to get similar behaviour for NSURLSession? I have read through the docs and tried various ways of configuring the session with no success.
NSURLSession works at an "upper" level, and is made to be more simple for the developer than using NSURLConnection.
I made some tests and I think that there is no possibility to control the runloop and the mode of NSURLSession, because they seems to be managed by an external daemon and not by your App (I tested only with NSURLSessionDownloadTask).
Do this simple test:
download and execute this Github project
start a download
open the "downloads" controller to see the state of your download
pause the app
wait a moment
unpause the app
you will see that the download has been continued while your app was paused, so when you start a NSURLSession the control is passed to the system, outside your app: it means that the main part of the work doesn't take place in an internal runLoop.
The only thing you have control on, is the serial queue on which the delegate calls are dispatched (passed back to your application). The delegate calls are queued for execution (on the main or on a background thread, you can choose it), since NSOperationQueue use Grand Central Dispatch to queue the calls, I'm not sure about the runloop mode used for this, but I think this is a good starting point to continue your researches.
EDIT:
If I remember correctly, dispatch calls made on background threads are made on threads where a runloop is not running. In fact, if you add this line
NSLog(#"%#", [[NSRunLoop currentRunLoop] currentMode]);
on one of the delegate methods of the FLDownloader class in the previous project, you will see that there is no run mode (nil), this happens when the runloop is not running.
If anyone ever runs into this problem again. You can't schedule the download task into a different run loop but you can handle the response in a different run loop mode which still greatly improves the performance while scrolling.
[self performSelectorOnMainThread:#selector(requestDidFinishLoadingWithData:)
withObject:data
waitUntilDone:YES
modes:#[NSDefaultRunLoopMode]];
I have problem suspending the current task being executed, I have tried to set NSOperationQueue setSuspended=YES for pausing and setSuspended=NO for resuming the process.
According to apple docs I can not suspend already executing task.
If you want to issue a temporary halt to the execution of operations, you can suspend the corresponding operation queue using the setSuspended: method. Suspending a queue does not cause already executing operations to pause in the middle of their tasks. It simply prevents new operations from being scheduled for execution. You might suspend a queue in response to a user request to pause any ongoing work, because the expectation is that the user might eventually want to resume that work.
My app needs to suspend the time taking upload operation in case of internet unavailability and finally resume the same operation once internet is available. Is there any work around for this? or I just need to start the currently executing task from zero?
I think you need to start from zero. otherwise two problems will come there. If you resume the current uploading you cant assure that you are not missed any packets or not. At the same time if the connection available after a long period of time, server may delete the data that you uploaded previously because of the incomplete operation.
Whether or not you can resume or pause a operation queue is not your issue here...
If it worked like you imagined it could (and it doesn't) when you get back to servicing the TCP connection it may very well be in a bad state, it could have timed out, closed remotely...
you will want to find out what your server supports and use the parts of a REST (or similar) service to resume a stalled upload on a brand new fresh connection.
If you haven't yet, print out this and put it on the walls of your cube, make t-shirts for your family members to wear... maybe add it as a screensaver?
I am creating a user defined thread library. I use Round-Robin scheduling algorithm and use the context switching method. But, I am unable to know what to do when a thread finishes its execution before the allotted time slot. The program is getting terminated. I actually want to reschedule all the threads, by calling the schedule function when the current thread gets terminated.
I found two ways to overcome this problem.
By calling explicitly thread_exit function at the end of the function that is being executed by the current thread.
By changing the stack contents such that the thread_exit function gets executed after the current function gets terminated.
But I am unable to find how to apply these solutions....
Anybody out there... plz help me...
It sounds like you have a bit of a design flaw. If I'm understanding you correctly, you're trying to implement a solution where you have threads that can be allocated to perform some task and after the task is complete, the thread goes idle waiting for the next task.
If that's true, I think I would design something like a daemon process or service that manages a queue for tasks coming in, a pool of threads responsible for executing the tasks with a controller that listens for new tasks.
I am developing a project for BB. The application works with the network and sends / receives data via HTTP. Now I use the queue and queue manager. Manager starts with a background thread and works in while (true) loop, checking the queue for new transactions to the server. If the queue is not empty, then the transaction is executed, otherwise the manager goes to sleep for 200 ms.
The process of the transaction as follows:
- Runs another thread (using the Runnable), which opens a connection to the network and first thread waiting for background thread or timeout (and for that we need a loop), which we set.
- If the connection is established, then starts another thread (using the Runnable), which runs getResponseCode (), and first thread waiting for background thread or timeout (and for that we need a loop), which we set.
Before it, we showing popup window with wait-rotating-image, and after it is removed. It synchronized via Application.getEventLock ().
Iit unstable sometimes and thread sleeps for a long time ignore timeout-waiting-loop.
I would like to know how valid such an approach, what advice and best-practice is, what is your experience?
I use 4.5, 4.6, 4.7 and 5.0.
The lock returned by Application.getEventLock() should only be used for code that modifies the UI or UI components - it's the lock used by the event dispatcher. You should not be using it for background tasks such as HTTP processing. If you want to synchronize that code, it would be best to just create your own lock object.
You do not need that many threads, your EDT (event dispatch thread a.k.a main thread) should insert he job (some runnable class) into a queue and use wait/notify to inform a dedicated worker thread, that is responsible for network transaction, to check the queue.
The worker thread will be responsible for opening connection, writing to connection and reading from it.
For information about wait/notify mechanism check out:
A simple scenario using wait() and notify() in java
Due to the fact that you can't update the UI using the worker thread, Once the network transaction is completed you can update the UI layer using InvokeLater
For more details go to http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/Application.html#invokeLater(java.lang.Runnable)
you can set a timeout in the HTTPConnection itself, but if you don't want to rely on that mechanism, you can schedule a TimerTask that will execute after some time and handle the timeout in case no response is received.
Once the response is received all you need to do is cancel the TimerTask so that the timeout will not be triggered.
Check out http://www.blackberry.com/developers/docs/4.0api/java/util/TimerTask.html