gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSProgressIndicator movement inside a loop


From: Fred Kiefer
Subject: Re: NSProgressIndicator movement inside a loop
Date: Wed, 02 Mar 2005 14:00:32 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.2) Gecko/20040906

Frederico Muñoz wrote:

So, here is the problem: in the .pkg bundle the installation at a
certain stage is simply copying a directory to another location. Since
I want to do it file by file I use NSDirectoryEnumerator and copy the
file. I want to have progress bar (progressIndicator) to advance each
time a file is copied, and optionally display the name of the file
above it, etc. I can't pass the NSProgressIndicator to
packageManager's installPackage method since that would ruin the
separation between view and model. This was my first problem. I
decided (but I'm open to suggestions on a better way to do it, I
couldn't think of any...) that the installPackage method would check
for the presence of a updateProgress method in the sender and call it
each time it did something worthy of progression (updateProgress then
uses [progressIndicator incrementBy: X] and related methods to deal
with the progress bar). Simply doing a [sender updateProgress] didn't
work, and this because the NSProgressIndicator is only advanced after
an exit from the method (the run loop only draws theNSProgressIndicator after exiting the installPackage method, no matter how many times i call [progressIndicator display] and related methods). I decided to use:

[NSThread detachNewThreadSelector:@selector (installPackage:)
            toTarget:packageManager
            withObject:self];

to overcome this (please disregard the "self" bit, I'm just
experimenting for now). I set a autorelease pool in the installPackage
method as per the documentation and now it works, I call [sender
updateProgress] inside the copy loop and the progress bar is updated
in real time. However it was brought to my attention that mixing this
call inside a thread might not be very safe and would produce unpredictable
results. I tried with


Could you explain, what problems you are expecting from this approach? As far as I understand, you where just changing the progress indicators state and marking it for redraw (done by IncrementBy:). This should be fine even from a background process. I admit that most of the GUI code isn't currently thread safe, but in this special case no harm should follow. It may be different for your code to display the file name, but you did not give any details on that. What you need to keep in mind is never to draw from a background thread, and this you seem to have respected.

[sender performSelectorOnMainThread: @selector(updateProgressWithFile:)
                    withObject: file waitUntilDone: NO];

to be more thread friendly but this doesnt work, since not having it
executing in the main thread (to escape the run loop draw timing) was
the reason I created the thread in the first place, and this way the
problem reapears, the progress bar is only updated after the loop
exits.


This approach should work (if you set waitUntilDone to YES), but it is really not needed. What may cause it to fail for you, is that your background thread does not yield to the main thread, so this never gets a chance to execute. I must admit, I am missing the details on thread switching for the different thread models GNUstep supports.

Fred




reply via email to

[Prev in Thread] Current Thread [Next in Thread]