Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在主线程上启动对话框,等待工作线程的结果_C++_Multithreading_Mfc_Cpprest Sdk - Fatal编程技术网

C++ 在主线程上启动对话框,等待工作线程的结果

C++ 在主线程上启动对话框,等待工作线程的结果,c++,multithreading,mfc,cpprest-sdk,C++,Multithreading,Mfc,Cpprest Sdk,我有一个应用程序,它发送HTTP请求并处理收到的响应。主线程被阻塞,直到响应返回,否则我们无法处理数据。要发送这些请求,必须对用户进行身份验证。我希望捕获401响应,在返回响应供我的应用程序处理之前,提示用户进行身份验证。根据成功与否,我希望重试发送原始请求并返回该响应,或者,如果身份验证失败,则返回原始401响应 我使用C++ REST SDK发送HTTP请求。这些事件发生在另一个线程(pplx::task)中。我还使用MFC模式对话框提示进行身份验证。有些人可能会看到出现的死锁。如果没有,让

我有一个应用程序,它发送HTTP请求并处理收到的响应。主线程被阻塞,直到响应返回,否则我们无法处理数据。要发送这些请求,必须对用户进行身份验证。我希望捕获401响应,在返回响应供我的应用程序处理之前,提示用户进行身份验证。根据成功与否,我希望重试发送原始请求并返回该响应,或者,如果身份验证失败,则返回原始401响应

我使用C++ REST SDK发送HTTP请求。这些事件发生在另一个线程(pplx::task)中。我还使用MFC模式对话框提示进行身份验证。有些人可能会看到出现的死锁。如果没有,让我进一步解释

主线程等待HTTP请求完成。在该线程中,我捕捉到一个401并希望启动一个对话框。为此,我使用了一个
boost::signal
。此信号调用
SendMessage
到我希望显示对话框的句柄。消息被MFC消息循环处理后,它将启动对话框(在主线程上)。这依赖于MFC消息循环,它在等待HTTP请求时被阻塞。简言之,主线程已经在等待请求完成,因此它无法运行消息循环来接收来自
SendMessage
的调用


主线程正在工作线程上等待。工作线程需要在主线程上启动一个对话框,然后才能继续。僵局有人有什么聪明的解决办法吗?

我认为最简单的解决办法是重新设计处理线程的方式

我建议不要为请求使用单个线程,而是为每个请求生成一个新线程,然后让它返回状态码(不管是什么),然后可以处理任何逻辑,以便在主线程内重试身份验证(即显示一个身份验证对话框,然后使用凭据重新启动身份验证线程)

这还允许您更好地封装请求处理程序,这是一个很大的优点。为了正确封装此逻辑(因此您不必检查每个请求),您应该定义某种请求处理程序(类或函数)。例如

StatusCode生成请求(…){
//在这里处理身份验证的逻辑
}
其中StatusCode是HTTP状态代码的类型


当然,这并不能解决UI线程可能等待工作线程完成的问题,因此您还需要某种UI刷新方法,该方法每x时间调用一次,并检查所有工作线程的状态(即通过检查返回的
std::future
)。在这种情况下,您还需要更改我上面的示例,以可能生成一个单独的线程,并返回一个
std::future

您肯定想使用线程,但需要让UI线程“呼吸”。如果有任何问题,请禁用除“取消”按钮之外的所有控件。不要“等待”让这些线程在线程基础上完成。相反,让它们通过方法调用(或者更好,在对话框中调用“更新状态”方法,以获得每个线程状态或完成百分比或???)的更高分辨率。您的描述有点混乱。您有多少个对话框?只有一个(用于认证)更多?此外,身份验证对话框的显示是要采取的第一个操作,还是也必须等待某个HTTP请求完成?请以更详细的方式,最重要的是以正确的顺序,描述所需操作和事件的顺序。为简单起见,让我们只说有主对话框和身份验证对话框日志。与主对话框交互会触发HTTP请求。我最关心的是身份验证过期并尝试发送请求。在实践中,这种情况应该很少发生。如果发生,我希望打开身份验证对话框并重试请求。以下是流程:用户单击主对话框中的btn。btn触发HTTP。如果是200,则显示响应结果。If 401,显示身份验证对话框。如果成功,请重试HTTP。如果响应是另一个失败或身份验证失败,则假设程序关闭。因此,您的第一个操作是显示主对话框。问题是,如果未执行身份验证,是否允许用户在主对话框中执行任何操作?如果没有,则可能是更好的设计选择先执行身份验证,并仅在成功时显示主对话框。用户可以在不进行身份验证的情况下执行有限的操作。大多数情况下,用户在首次启动时会自动登录或提示。因此通常这不是问题。但是,如果应用程序长时间打开(并且没有刷新令牌)AUTH可能到期,意味着他们的请求会失败。在这一点上,他们必须手动提示登录。如果发生在一系列请求的中间失败,则将数据放在无效状态中可能是不好的。理想地,我会等待它们再次登录,重新发送失败的请求,并继续其路径。每个请求都是HA。我有自己的线程。我总是可以在处理每个响应之前检查状态,但我希望在内部处理401案例,这样在外部我就可以只担心响应内容。在内部,比如在HTTP请求流中的函数或类中。否则,我每次都必须检查并提示授权访问请求。理想情况下,我可以在返回响应之前拦截和处理请求(仅适用于401),然后对其内容进行处理。当然,因此将其放入一个函数中,该函数在可能重试身份验证后返回最终代码。我可以同步封装该请求,但如果发出异步请求(返回线程),状态代码在加入之前是未知的。此时,状态代码已被读取