当 InternetOpenURL 尝试(但失败)连接时,如何避免 CPU 完全使用或终止?

发布于 2024-12-05 02:42:04 字数 1385 浏览 1 评论 0原文

我有一个相当简单的应用程序,它在线程中下载文件。此线程使用 WinINet API,并开始如下:

    HINTERNET hInternet = InternetOpen(strUserAgent.c_str(), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    DWORD dwFlags = INTERNET_FLAG_NO_UI | INTERNET_FLAG_HYPERLINK | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD;
    HINTERNET hUrl = InternetOpenUrl(hInternet, m_strURL.c_str(), L"", 0, dwFlags, NULL);

但是,如果没有互联网连接,或者远程主机已关闭,InternetOpenUrl 将需要很长时间才能超时并完成。当它执行此操作时(也就是说,仅在无法连接到远程主机的情况下),它将使用一个 CPU 的 80-100%,直到它最终返回。由于超时延迟设置,这种情况通常会持续一分钟左右。在一个系统上,尽管有超时设置(如下所述),这种情况仍会持续长达十分钟。

我该如何:

  • 在尝试连接时避免如此大量的 CPU 使用?
  • 如果我想关闭应用程序,请通知线程终止?通常超时是可以的,但如果应用程序需要关闭,那么它将等待该线程完成,这会花费大量 CPU 在 InternetOpenUrl 内执行很少的操作。

[旁白:InternetQueryOption 显示的我系统上的当前超时设置:

  • INTERNET_OPTION_CONNECT_TIMEOUT:60 秒
  • INTERNET_OPTION_RECEIVE_TIMEOUT:30 秒
  • INTERNET_OPTION_SEND_TIMEOUT:30 秒

更改这些会减少方法放弃并返回之前的时间,因此减少了使用这么多 CPU 所花费的时间,但可能会影响连接 - 之后总之,超时是有原因的。该应用程序可用于奇怪的连接情况,例如在船上,连接可能是通过卫星进行的,延迟较高,并且比标准桌面互联网连接需要更长的时间。我不知道合理的超时是多少。此外,必须有一种更好的方法来避免 CPU 使用并比简单地缩短超时更快地终止。]

I have a fairly simple application which downloads files in a thread. This thread uses the WinINet APIs, and begins like so:

    HINTERNET hInternet = InternetOpen(strUserAgent.c_str(), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    DWORD dwFlags = INTERNET_FLAG_NO_UI | INTERNET_FLAG_HYPERLINK | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD;
    HINTERNET hUrl = InternetOpenUrl(hInternet, m_strURL.c_str(), L"", 0, dwFlags, NULL);

However, if there is no internet connection, or the remote host is down, InternetOpenUrl will take a long time to time out and complete. While it is doing this - that is, only in the situation that it can't connect to the remote host - it will use between 80-100% of one CPU until it finally returns. This can often continue for a minute or so, because of the timeout delay setting. On one system, in spite of the timeout settings (noted below), this has continued for up to ten minutes.

How do I:

  • Avoid such massive CPU usage when it's just trying to connect?
  • Signal the thread to terminate if I want to shut down the app? Normally a timeout is fine, but if the app needs to close then it will wait on this thread to finish, which is spending lots of CPU doing very little inside InternetOpenUrl.

[Aside: Current timeout settings on my system, as revealed by InternetQueryOption:

  • INTERNET_OPTION_CONNECT_TIMEOUT: 60s
  • INTERNET_OPTION_RECEIVE_TIMEOUT: 30s
  • INTERNET_OPTION_SEND_TIMEOUT: 30s

Changing these would decrease the time before the method gave up and returned and so decrease the time spent using so much CPU, but might affect connecting - after all, the timeouts are there for a reason. This app can be used in odd connection situations, such as on board ship, where connecting could potentially be over satellite with high latency and take longer than a standard desktop internet connection. I do not know what reasonable timeouts would be. Also, there has to be a better method to avoid the CPU usage and terminate more quickly than simply shortening the timeouts.]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼中杀气 2024-12-12 02:42:04

您可以在异步模式下使用WinInet。不确定是否解决了 CPU 利用率问题,但可以正确处理终止。

You can use WinInet in asynchronous mode. Not sure whether it solves CPU utilization issue but termination can be handled properly.

魂ガ小子 2024-12-12 02:42:04

我认为您可以使用 InternetCloseHandle 关闭从 InternetOpen 返回的会话句柄。

根据 http://msdn.microsoft.com/ en-us/library/aa384350(v=VS.85).aspx 它将取消阻止该句柄上的任何挂起操作。

因此,基本上,如果您将 InternetOpenUrl 保留在单独的线程中,您仍然可以从父线程中关闭会话句柄(如果您在异步模式下使用它,则不需要单独的线程)。您可以为任何资源清理设置状态回调函数。

如果要设置不同的超时,请使用 InternetSetOption。

PS:我使用WinINet库做任何事情已经有一段时间了,所以我不能保证上述方法一定有效。

I think you can close the session handle returned from InternetOpen with InternetCloseHandle.

According to http://msdn.microsoft.com/en-us/library/aa384350(v=VS.85).aspx it will unblock any pending operation on that handle.

So basically if you keep InternetOpenUrl in a separate thread, you can still close the session handle from the parent thread(a seperate thread is not required if you are using it in async mode). You can set a status callback function for any resource cleanup.

If you want to set a different timeout, use InternetSetOption.

PS: Its been a while I've done anything with WinINet library, so I cannot guarantee that the above method will work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文