How to avoid full CPU utilisation, or terminate, while InternetOpenURL is trying (and failing) to connect?

匆匆过客 提交于 2019-12-23 02:48:05

问题


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.]


回答1:


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




回答2:


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.



来源:https://stackoverflow.com/questions/7443696/how-to-avoid-full-cpu-utilisation-or-terminate-while-internetopenurl-is-trying

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!