Не уверен, почему, но случайным образом при вызове функции InternetQueryDataAvailable
возникает исключение null ref без видимой причины, поскольку ни один из аргументов, которые он принимает, не может быть нулевым:
[DllImport(Dlls.Wininet, SetLastError = true)]
public static extern bool InternetQueryDataAvailable([In] IntPtr hFile, [Out] out int numberOfBytesAvailable, [Optional, In] int reserved0, [Optional, In] IntPtr reserved1);
Вот исключение:
И нет, CheckHandle()
не является виновником, поскольку все, что он делает, это проверяет, является ли _handle
нулем или нет, то есть недействительным.
Кроме того, если это не так, то после загрузки всех данных и попытки закрыть приложение, грехи, которые я настроил, чтобы все дескрипторы закрывались до закрытия приложения, вызов InternetCloseHandle
даже вызывает исключение null ref, как и в случае с InternetQueryDataAvailable
, ни один из аргументов не может принимать значения NULL, поскольку все, что он принимает, это один IntPtr
:
[DllImport(Dlls.Wininet, SetLastError = true)]
public static extern bool InternetCloseHandle([In] IntPtr hInternet);
Я не уверен, что происходит, потому что в редких случаях все работает нормально, и я могу загрузить все данные и закрыть дескриптор без создания случайного исключения.
Для тех, кому интересно, как выглядит функция с InternetCloseHandle, это просто:
public void Dispose()
{
if (_handle != IntPtr.Zero)
{
if (!WinINet.InternetCloseHandle(_handle))
{
throw new Win32Exception();
}
_handle = IntPtr.Zero;
}
}
Обратите внимание, что исключение, которое выдается после вызова InternetQueryDataAvailable
, возникает только после первого вызова, поэтому первый вызов в порядке, но все последующие имеют шанс вызвать исключение.
_handle
равенIntPtr
, даже если бы он был равен нулю, 1) пользовательское исключение будет вызвано из-за CheckHandle, 2) исключение нулевой ссылки было бы невозможно, посколькуIntPtr
не может быть обнулено, и даже если проблема была с_handle
что это не так, поскольку он указывает на действительный файл данных HTTP-запроса,InternetQueryDataAvailable
возвращает логическое значение, которое указывает, успешно ли он завершен или нет, и не должен генерировать исключения, особенно неуправляемые С#. - person Vincent Bree   schedule 31.10.2019Note that the exception which is thrown after calling InternetQueryDataAvailable only occurs after the first call
, первый вызов успешен, и нет, я не вызываюInternetCloseHandle
сразу после этого, после него я вызываюInternetReadFile
, который затем возвращается кInternetQueryDataAvailable
, и это продолжается до тех пор, пока либо возврат из запроса не станет ложным, либо число байт равно нулю, только после этого дескриптор закрывается, поэтому нет, дескриптор действителен на протяжении всей процедуры. - person Vincent Bree   schedule 31.10.2019InternetQueryDataAvailable(_handle, out numberOfBytes, 0, IntPtr.Zero);
, но это ничего не изменило, исключение null ref все еще возникает. - person Vincent Bree   schedule 31.10.2019