Re: Challenge: Block Main Thread while Work is done, with Timeout
Re: Challenge: Block Main Thread while Work is done, with Timeout
- Subject: Re: Challenge: Block Main Thread while Work is done, with Timeout
- From: Jerry Krinock <email@hidden>
- Date: Fri, 24 Jul 2009 14:50:27 -0700
On 2009 Jul 23, at 17:44, Ken Thomases wrote:
On Jul 23, 2009, at 6:44 PM, Jerry Krinock wrote:
I'd often like to block the main thread
First question is: why? Blocking the main thread is usually bad and
to be avoided. What are you actually trying to achieve? Can you
give an example of when that would be desirable?
This happens any time that a user action absolutely requires some
little job be done in a low-leve method before proceeding, but this
job fails on rare occasions.
For example, say a user action requires that data be read in from a
file known by a file alias which must be resolved. It can't continue
without the resolved path, but if it's on a remote volume that was not
properly dismounted, Alias Manager will beachball my app for 150
seconds before giving up.
The notifications don't cross threads; they are delivered in the
thread where they are posted.
Yes, I understand that. There must be some quirk that allows it to
work when doing an NSTask
If you really want to use a run loop in this manner, you could use a
port. The SSYThreadBlocker would be the port's delegate to handle
messages it receives; it would run the run loop to allow messages to
be received and processed; the worker thread would send them. You
might consider using a private run-loop mode, though, so the run
loop is only processing your input source.
Yes, when I read the documentation, I thought the same thing. "Oh,
OK, I just need to add a port." After writing a bunch of code that
didn't work, I gave up on it.
Do consider NSConditionLock as an alternative, though. It's likely
to be much simpler and more straightforward.
Yes, I've been using NSOperation for so long now that I forgot about
old NSConditionLock. Although used more commonly to protect access
across threads, it is in fact exactly what I need -- to block a thread
until some condition.
Thanks, Ken!
The final, working code is probably a little too long to post in here,
because I also ended up #importing my NSInvocation-maker category. So
I'm just pasting in the @interface. One of these days I'll get this
stuff up on a version control server somewhere. If anyone wants it in
the meantime, just let me know privately.
@interface SSYThreadPauser : NSObject {
}
/*!
@brief Runs a job on another thread and blocks the current
thread until the method is complete, or until a timeout, whichever
happens first.
@details If timeout occurs, the workerThread will be sent
a -cancel message, so that if your worker periodically sends -
isCancelled
to its current thread, it can abort the work in order to stop wasting
cpu cycles. See -[NSThread isCancelled] documentation.
@param worker The target which will perform the job.
@param selector The selector of the job to be run. This
method need not create nor drain an autorelease pool if garbage
collection
is not being used, because SSYThreadPauser takes care of that.
@param object A parameter which will be passed to selector
@param workerThread The thread on which the job will be performed.
If you pass nil, a temporary thread will be created.
@param timeout The timeout before the job is aborted.
@result YES if the job completed, NO if it timed out.
*/
+ (BOOL)blockUntilWorker:(id)worker
selector:(SEL)selector
object:(id)object
thread:(NSThread*)workerThread
timeout:(NSTimeInterval)timeout ;
@end
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden