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

Winapi 当InternetOpenURL尝试(但失败)连接时,如何避免CPU完全使用或终止?,winapi,cpu-usage,wininet,Winapi,Cpu Usage,Wininet,我有一个相当简单的应用程序,可以在线程中下载文件。此线程使用,开始时如下所示: 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 | INTE

我有一个相当简单的应用程序,可以在线程中下载文件。此线程使用,开始时如下所示:

    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);
但是,如果没有internet连接,或者远程主机关闭,则需要很长时间才能超时并完成。当它这样做时——也就是说,只有在无法连接到远程主机的情况下——它将使用一个CPU的80-100%,直到它最终返回。由于超时延迟设置,这通常会持续一分钟左右。在一个系统上,尽管有超时设置(如下所述),但这种情况仍持续了10分钟

我如何:

  • 在尝试连接时避免如此大量的CPU使用
  • 如果要关闭应用程序,请向线程发送终止信号?通常超时是可以的,但如果应用程序需要关闭,它将等待该线程完成,这将花费大量CPU在
    InternetOpenUrl
    内部做的很少

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

  • 互联网\u选项\u连接\u超时
    :60s
  • 互联网\u选项\u接收\u超时
    :30秒
  • 互联网\u选项\u发送\u超时
    :30秒

更改这些将减少方法放弃和返回之前的时间,从而减少使用如此多CPU所花费的时间,但可能会影响连接-毕竟,超时是有原因的。此应用程序可以在奇怪的连接情况下使用,例如在船上,连接可能通过高la的卫星tency并且比标准桌面internet连接需要更长的时间。我不知道什么是合理的超时。此外,必须有更好的方法来避免CPU使用,并比简单地缩短超时更快地终止。]

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

根据协议,它将解除对该句柄的任何挂起操作的阻止

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

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


PS:我已经用WinINet库做了一段时间了,所以我不能保证上面的方法会起作用。

您可以在中使用WinINet。不确定它是否解决了CPU利用率问题,但可以正确处理终止。

这很奇怪。您是否在许多计算机上遇到过这种CPU阻塞问题,还是仅在您的计算机上?我不指望WinInet会有这样的行为。它至少在两台机器上运行:WMWare Fusion机器上的Windows 7(我的-但在我的机器上,它只会达到80%)和第二台机器上的Windows XP(我想是一名QA工作人员的)。你试过在异步模式下使用WinInet吗?@Sergius:没有。事实上,我忘了它有一个异步模式。出现了一些专门提到终止的谷歌搜索。我想你应该加上这个作为答案!在这种情况下,我看不到任何CPU使用情况,并且几乎立即返回一个错误。可能是硬件或驱动程序的问题。很有趣-所以我会调用InternetOpenUrl,但将返回的句柄传递给主线程,哪一个可以关闭它?我说的是你可以把InternetOpenUrl放在一个单独的线程中,当你想停止操作时,关闭你在主线程中作为第一个参数提供的HINTERNET句柄。阅读文档,这似乎是终止的最安全的选项。在赏金到期之前,我没有时间尝试,但听起来不错,所以给自己加分吧@David,虽然异步模式是使用WinINet库的推荐方式,但它对您的情况没有帮助。在您的情况下,InternetOpenUrl需要时间,因此在异步模式下,您也无法终止函数,除非您关闭会话句柄。@Vishal,InternetOpenUrl不应在异步模式下阻止。@Sergius,同意InternetOpenUrl在异步模式下不会阻止,但它需要完成并返回句柄才能对该句柄进行任何处理。从术语上讲,把它放在一个单独的线程中并没有更好的效果。