【发布时间】:2020-03-20 17:53:06
【问题描述】:
我有一个应用程序可以发送 HTTP 请求并处理收到的响应。主线程被阻塞,直到响应返回,否则我们无法处理数据。要发送这些请求,用户必须经过身份验证。我希望捕获 401 响应,并在返回响应以供我的应用程序处理之前,提示用户进行身份验证。根据成功与否,我想重试发送原始请求并返回 that 响应,或者,如果身份验证失败,则返回原始 401 响应。
我正在使用 C++ REST SDK 发送 HTTP 请求。这些发生在另一个线程(pplx::task)中。我还使用 MFC 模式对话框来提示身份验证。你们中的一些人可能会看到发生的死锁。如果没有,让我再解释一下。
主线程等待 HTTP 请求完成。在该线程中,我捕获了 401 并希望启动一个对话框。为此,我使用boost::signal。该信号将SendMessage 调用到我希望显示对话框的句柄。在消息被 MFC 消息循环处理后,它将启动对话框(在主线程上)。这依赖于 MFC 消息循环,该循环在等待 HTTP 请求时被阻塞。简而言之,主线程已经在等待请求完成,因此它无法运行其消息循环来接收来自SendMessage 的调用。
主线程正在等待工作线程。工作线程需要在主线程上启动一个对话框才能继续。僵局。有没有人有任何聪明的解决方案来解决这个问题?
【问题讨论】:
-
你肯定想要使用线程,但你需要让你的 UI 线程“呼吸”。如果有的话,禁用除取消按钮之外的所有控件。不要“等待”这些线程以线程为基础完成。相反,让他们通过方法调用通知对话框他们的结果(或者更好的是,在对话框中调用“更新状态”方法以获得每个线程的状态或完成百分比或???)的更多分辨率。
-
您的描述有点混乱。你有多少对话框?只有一个(用于身份验证)或更多?此外,验证对话框的显示是要采取的第一个操作,还是必须等待某些 HTTP 请求完成?请更详细地描述所需的操作和事件的顺序,最重要的是按正确的顺序。
-
为简单起见,我们只说有主对话框和身份验证对话框。与主对话框交互会触发 HTTP 请求。我最关心的是身份验证过期并尝试发送请求。在实践中,这应该很少发生。如果是这样,我想打开身份验证对话框并重试请求。流程如下:用户在主对话框中单击 btn。 Btn 触发 HTTP。如果为 200,则显示响应结果。如果是 401,则显示身份验证对话框。如果成功,请重试 HTTP。如果响应是另一个失败或身份验证失败,那么假设程序关闭。
-
所以你的第一个动作是显示主对话框。问题是,如果尚未执行身份验证,是否允许用户在主对话框中执行任何操作?如果没有,最好先执行身份验证并仅在成功时显示主对话框。
-
用户可以在没有身份验证的情况下执行有限的操作。大多数情况下,用户在首次启动时会自动登录或提示。所以通常这不是问题。但是,如果应用程序长时间打开(并且没有刷新令牌),则身份验证可能会过期,这意味着他们的请求将失败。此时他们必须手动提示登录。如果它碰巧在一系列请求的中间失败,那么将数据置于无效状态可能会很糟糕。理想情况下,我会等待他们再次登录,重新发送失败的请求,然后继续。
标签: c++ multithreading mfc cpprest-sdk