Как избежать полной загрузки ЦП или прекратить работу, пока InternetOpenURL пытается (и не может) подключиться? - PullRequest
1 голос
/ 16 сентября 2011

У меня довольно простое приложение, которое загружает файлы в потоке.Этот поток использует WinINet APIs и начинается следующим образом:

    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 займет много времени и закончится.Пока он делает это - то есть, только в том случае, если он не может подключиться к удаленному хосту - он будет использовать от 80 до 100% одного ЦП, пока он, наконец, не вернется.Это часто может продолжаться в течение минуты или около того, из-за настройки времени ожидания.В одной системе, , несмотря на настройки времени ожидания (отмеченные ниже), это продолжалось до десяти минут.

Как мне:

  • Избегатьтакое интенсивное использование процессора, когда он просто пытается подключиться?
  • Сигнализировать потоку прерывание, если я хочу закрыть приложение?Обычно время ожидания хорошее, но если приложение должно закрыться, оно будет ждать завершения этого потока, который тратит много ресурсов ЦП, делая очень мало внутри InternetOpenUrl.

[В стороне: текущие настройки тайм-аута в моей системе, как показывает InternetQueryOption:

  • INTERNET_OPTION_CONNECT_TIMEOUT: 60 с
  • INTERNET_OPTION_RECEIVE_TIMEOUT: 30 с
  • INTERNET_OPTION_SEND_TIMEOUT: 30 с

Изменение этих значений уменьшит время до того, как метод завершит работу и вернется, и, следовательно, сократит время, затрачиваемое на использование столь большого количества ЦП, но может повлиять на подключение - в конце концов, таймауты существуют по причине.Это приложение может использоваться в нечетных ситуациях подключения, например, на борту судна, где подключение может потенциально осуществляться через спутник с высокой задержкой и занимать больше времени, чем стандартное подключение к Интернету на рабочем столе.Я не знаю, какие будут разумные тайм-ауты.Кроме того, должен быть лучший способ избежать использования ЦП и завершаться быстрее, чем просто сокращать время ожидания.]

Ответы [ 2 ]

1 голос
/ 24 сентября 2011

Вы можете использовать WinInet в в асинхронном режиме . Не уверен, решает ли это проблему с использованием ЦП, но завершение может быть обработано правильно.

1 голос
/ 21 сентября 2011

Я думаю, что вы можете закрыть дескриптор сеанса, возвращенный из InternetOpen, с помощью InternetCloseHandle.

Согласно http://msdn.microsoft.com/en-us/library/aa384350(v=VS.85).aspx он разблокирует все ожидающие операции с этим дескриптором.вы держите InternetOpenUrl в отдельном потоке, вы все равно можете закрыть дескриптор сеанса из родительского потока (отдельный поток не требуется, если вы используете его в асинхронном режиме).Вы можете установить функцию обратного вызова состояния для любой очистки ресурса.

Если вы хотите установить другое время ожидания, используйте InternetSetOption.

PS: Давно я что-то делал с библиотекой WinINet, поэтому я не могу гарантировать, что вышеуказанный метод будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...