Bill Burns wrote: > I'm trying to make a small, threaded FTP app and I'm running into > a problem. > > My program has a GUI (I use PythonCard) and I want the GUI to be > responsive while network operations are going on. > > I assumed that if I made a class (shown below) which was sub-classed > from threading.Thread - I wouldn't have any problems. > > My GUI class (not shown) has a 'connect' button with a method that > looks like this: > > def on_connect_command(self, event): > """Connect to the remote server.""" > # getConnectData() -> returns a tuple with > # all of the data we need to connect. > server, username, password = self.getConnectData() > # Instantiate my threaded FTP class. > self.host = FTP(server, username, password) > self.host.setDaemon(True) > self.host.start() > time.sleep(1) > > When I hit this button, the GUI is completely responsive while trying to > connect to the remote server. I have no problems and everything works as > expected.
In this method you create a new thread and start it. The thread's run() method is called. It connects to the remote server, fetches and prints a directory and returns. At that point (when the run() method returns) the FTP thread is dead. > > Here's where I get the problem... The GUI class has another method which > looks like this: > > def on_getData_command(self, event): > # getDirectoryData(...) is a method in the > # FTP() class. It walks a remote directory. > self.host.getDirectoryData(someDirectory) > > When I fire this method - it blocks until getDirectoryData() returns, > which makes the GUI non-responsive. It's *not* hanging due to a network > problem (it will only fire if you're connected to the remote server.) > > Why does this one method block? I assumed it would run in the FTP class > thread and I'd have no problems!? What should I do different? No, you don't do anything here to make the getDirectoryData() method run in a separate thread. Just because the FTP class has (or had) one thread at one time doesn't automatically make all of the FTP class methods run in a different thread. There are a few different ways you could handle this. You could have each command in the FTP class be smart enough to start a new thread to run the command. You don't actually have to subclass threading.Thread, you can just create a thread and tell it what method to execute. (Side note - this might be a good use for a @run_in_thread decorator.) You could make a separate class for each command. This would be pretty similar to the above solution. You would probably want a base class or utility class to hold the common details of connecting and sending a command. You could make a thread that really does keep running, that listens to for commands from a Queue. Your GUI thread would put a command in the Queue, the daemon thread would pull a command out and execute it. You could figure out how to do this with Twisted... HTH, Kent _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor