Wow - thank you.  This helps a lot.  I've read the thread programming guide - I 
just wish it included more high-level design considerations and suggestions 
such as these.  Thanks again, Tom

___________________________________

Thomas Fortmann
Director of Development         
Xcape Solutions, Inc. 


-----Original Message-----
From: Ken Thomases [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, September 10, 2008 9:13 AM
To: Tom Fortmann
Cc: cocoa-dev@lists.apple.com
Subject: Re: Best approach to long running tasks.

On Sep 10, 2008, at 7:58 AM, Tom Fortmann wrote:

> I'm looking for suggestions on how to best handle long running  
> tasks.  My
> app has a simple button connected to an Objective-C method.  When I  
> click
> the button the method is called and a series of steps are  
> performed.  Each
> involves some network activity and may take a second or two.  I  
> would like
> to update a status message on the screen as each step is performed.   
> I've
> tried simply appending text to a text view, but none of the updates  
> get
> displayed until the whole method completes.  I also tried starting an
> NSThread from the method, allowing it to return, and letting the  
> thread
> update the text, but again nothing gets displayed until the thread
> completes.  Can anyone suggest a better way to handle this type of
> application?

In general, you have to be very careful about performing GUI updates  
from background threads.  There are a lot of things that you shouldn't  
do.  See the Threading Programming Guide 
<http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/ 
 >.

There are a couple of approaches to your problem.  One is to use  
asynchronous network APIs, like those provided by NSURLDownload,  
NSURLConnection, NSFileHandle, and NSStream.  The usual technique is  
to create an object of a custom class to represent the overarching  
task. This object maintains the state and coordinates the subtasks.   
It uses one of the above classes to perform its subtasks in an  
asynchronous fashion and uses the delegate or notification interface  
that they provide to handle each event as subtasks complete.

The reason that your updates aren't being displayed on screen is  
because you're not returning to the event loop, which displays any  
windows which have views that have been marked as needing display.   
You _can_ issue displayIfNeeded messages to force displaying outside  
of the normal event loop, but it's discouraged.  Often, if you find  
yourself tempted to do that, it's a sign that your design is  
problematic.  You'll probably discover that your design will cause you  
other problems, in addition to the display issues.  For example, your  
app won't be doing proper event handling, either.  It will give the  
user the spinning color wheel cursor, which is a bad sign.  The user  
won't be able to click any Cancel button, if you decide to implement  
that.  Etc.

There is another possible approach, which is to use a "modal  
session".  See the NSApplication methods beginModalSessionForWindow:,  
runModalSession:, and endModalSession:.

Lastly, if you do use a background thread, it should not attempt to  
perform GUI updates.  Instead, it should inform the main thread of its  
progress (using performSelectorOnMainThread:).  The method that you  
invoke that way has the responsibility to update the GUI given the new  
state supplied by the background thread.

Cheers,
Ken=

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to