4

编辑:在此修订/更新之前这个问题的主要部分是如何终止 QThread。这已经解决了,问题正在修改为如何杀死正在进行的请求休息对象。

http://docs.python-requests.org/en/v0.10.4/user/advanced/#asynchronous-requests 使用异步请求似乎仍然阻塞 - 用户无法在帖子进行时取消帖子。

基本上这是需要的功能:当用户按下Stop Uploading时,上传必须立即停止,我可以使用 stop() 停止线程,但是只有在循环再次循环后才检查它是否应该停止。

所以基本上,应该可以使用异步请求,让我检查是否应该在请求期间取消它,但是,我不知道如何。

有什么建议么?帖子的前一部分仍然相关,所以它在下面。
请注意,如何终止 QThread 的初始问题已经解决,因此下面的代码并不太重要,它只是为了上下文,我现在需要帮助的就是我刚才描述的内容。




我一直在写一个程序,它是一个照片上传器,我已经创建了一个线程来上传文件。我不知道如何退出线程。我已经尝试过从这里读到的建议:

1)我尝试了一个 bool 标志,将它包装在方法和执行工作的 for 语句周围。

2)我使用了“with”,然后尝试设置异常。

我希望能够取消上传,最好是快速。我读过很多,总是建议在终止线程之前“清理”线程,老实说,我不知道“清理”是什么意思。但是,我认为我应该能够杀死线程 - 因为它所做的只是将图像的二进制数据发送到 TUMBLR api。请求是否提前取消无关紧要,因为它也会取消 api 中的上传。

无论如何,这是我的线程:

class WorkThread(QtCore.QThread):
    def __init__(self):
        QtCore.QThread.__init__(self)
        global w
        w = WorkThread
    def __del__(slf):
        self.wait()        
    def run(self):
        url = 'https://www.tumblr.com/api/write'
        files = os.listdir(directory)
        for file in files:
            file_path = os.path.join(directory + '\\' + file)
            file_path = str(file_path)
            if file_path[-3:] in ['bmp', 'gif', 'jpg', 'png', 'thm', 'tif', 'yuv']:
                self.emit(QtCore.SIGNAL('update(QString)'), "Uploading %s ..." % file_path)
                print smart_str(password)
                data = {'email': email, 'password': password, 'type': 'photo'}
                with open(file_path, 'rb') as photo:
                    r = requests.post(url, data=data, files={'data': photo})
                print r.content
        self.emit(QtCore.SIGNAL('update(QString)'), 'All finished! Go check out your stuff on tumblr :)\n')
        return

我就是这样称呼它的。

def upload(self):
    self.doneBox.clear()

    self.workThread = WorkThread()
    self.connect( self.workThread, QtCore.SIGNAL("update(QString)"), self.startUploading )
    self.workThread.start()

谁能建议我可以快速安静地终止线程?或者,如果您认为这不好,可以安全地停止它。

但是,如果我没有立即杀死它,并且它在方法中再次通过 for 循环run(),它将在用户按下“”时上传它正在上传的照片Stop Uploading。我不希望它这样做,我希望它在用户按下“ Stop Uploading”的那一刻停止上传当前照片。

谢谢。

4

2 回答 2

1

我不确定你在用它做什么,global w; w = WorkThread但这似乎毫无意义,因为你没有用它做任何事情。

在你的__init__()你想要一个标志:

def __init__(self):
    ...
    self._isRunning = False

在您的run()方法中,您只需检查此标志并在需要时退出:

def run(self):
    self._isRunning = True
    while True:
        if not self._isRunning:
            # clean up or close anything here
            return
        # do rest of work

也许添加一个简单的方便方法:

def stop(self):
    self._isRunning = False
    self.wait()

当文档提到清理时,他们正在谈论关闭您可能已经打开的资源,撤消可能部分启动的事情,或者在杀死线程对象之前您可能想要发出信号或处理的任何其他事情。对于您的上传者,您想在开始每个上传过程之前检查线程是否应该退出。这将使您有机会停止线程并使其退出,然后再继续进行另一项工作。

于 2012-02-22T06:39:16.423 回答
0

尝试终止它:

self.workThread.terminate()

这样做时要小心。由于您正在执行网络操作,因此无法停止它,但通常您会这样做:

# Logic...

if self.running:
  # Continue logic...

self.running从线程外部设置。

于 2012-02-22T05:17:00.990 回答