如何在单独的线程中调用方法并使用返回状态

时间:2015-12-27 19:36:13

标签: c++ multithreading pointers c++11 post

我有一个类,其中一个方法向附加了文件的主机发送POST请求(并在请求完成后删除文件)。这是准系统代码:

using namespace Poco;
using namespace Poco::Net;

FileUploader::FileUploader(std::string aPathToFile): fPathToFile(aPathToFile)
{
}

void FileUploader::uploadFileInSeparateThread()
{
    std::thread([&](){
        this->uploadFile();
    }).detach();
}

bool FileUploader::uploadFile()
{
    try {
        const Context::Ptr context(new Context(Context::CLIENT_USE, "", "", "~/Desktop/root.pem",Context::VERIFY_ONCE));
        Poco::Net::HTTPSClientSession httpsSession(HOST, 443,context);

        HTTPRequest request(HTTPRequest::HTTP_POST, "/path/to/service?key=<name_of_file_to_be_uploaded>", HTTPMessage::HTTP_1_1);
        request.setContentType("application/x-www-form-urlencoded");
        request.setKeepAlive(true);
        HTMLForm form;
        form.setEncoding(HTMLForm::ENCODING_MULTIPART);
        form.addPart("file", new FilePartSource(fPathToFile));
        form.prepareSubmit(request);

        httpsSession.setKeepAlive(true);
        httpsSession.setTimeout(Poco::Timespan(20, 0));
        form.write(httpsSession.sendRequest(request));

        Poco::Net::HTTPResponse res;
        std::istream &is = httpsSession.receiveResponse(res);
        Poco::StreamCopier::copyStream(is, std::cout);
        qDebug() << "Message: " << is.rdbuf() << endl;
        return true;
    }
    catch (Exception &ex)
    {
        qDebug() << "Damn: " << ex.displayText().c_str() << endl;
        return false;
    }
}

如果我这样调用这个类:

FileUploader uploader(tempfilePath.toStdString());
uploader.uploadFile();

它工作正常,但是在请求正在进行时,UI被阻止。所以我决定对它进行mutithread并创建一个新方法uploadFileInSeparataeThread。然后我打电话给

FileUploader *uploader = new FileUploader(tempfilePath.toStdString());
uploader->uploadFileInSeparataeThread();

这很好用,但问题是,uploader占用的内存永远不会被删除。所以我把它变成了一个独特的指针:

std::unique_ptr<FileUploader> uploader(new FileUploader(tempfilePath.toStdString()));
uploader->uploadFileInSeparataeThread();

这不起作用,我收到Damn, file does not exist错误,当我尝试在form.addPart("file", new FilePartSource(fPathToFile));部分上传的文件丢失时会发生错误。这可能是预期的,在调用方法结束的那一刻,唯一指针将超出范围。所以我尝试了这个:

FileUploader uploader(tempfilePath.toStdString());
std::thread thread([&] (FileUploader * newUploader) { newUploader->uploadFile(); }, &uploader);
thread.join();

现在这样可行,但它不是多线程的,当请求正在进行时,UI仍然被阻止。

如何正确地使用多线程,并使用uploadFile()的返回值删除成功POST请求后上传的临时文件?

1 个答案:

答案 0 :(得分:1)

在最后一次尝试中: 为什么在创建线程后立即调用std :: thread :: join()?它使主线程等到另一个线程结束。仅当uploadFile()方法结束时(在代码中的某个其他位置,您检查异步调用的函数的结果),调用join(),否则它将等待。

你可以通过设置一些变量退出或者发出一些信号来学习退出,只是以某种方式告知UI它已经结束并且线程可以在不强迫等待的情况下加入。