Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 调用wininet函数时,会发生随机NullReferenceException_C#_Windows_Winapi_Pinvoke_Wininet - Fatal编程技术网

C# 调用wininet函数时,会发生随机NullReferenceException

C# 调用wininet函数时,会发生随机NullReferenceException,c#,windows,winapi,pinvoke,wininet,C#,Windows,Winapi,Pinvoke,Wininet,不确定原因,但在调用函数InternetQueryDataAvailable时随机出现null ref异常,原因不明,因为它接受的参数中没有一个可以为null: [DllImport(Dlls.Wininet, SetLastError = true)] public static extern bool InternetQueryDataAvailable([In] IntPtr hFile, [Out] out int numberOfBytesAvailable, [Optional, I

不确定原因,但在调用函数
InternetQueryDataAvailable
时随机出现null ref异常,原因不明,因为它接受的参数中没有一个可以为null:

[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()
不是罪魁祸首,因为它所做的只是检查
\u handle
是否为零,即无效

此外,如果不是这样,那么在下载所有数据并尝试关闭应用程序后,我将其设置为在应用程序关闭之前关闭所有句柄,对
InternetCloseHandle
的调用甚至会抛出null ref异常,就像
InternetQueryDataAvailable
一样,所有参数都不可为空,它只接受一个
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
后引发的异常仅在第一次调用后发生,因此第一次调用没有问题,但之后的所有调用都有可能触发异常

请注意,调用InternetQueryDataAvailable后引发的异常仅在第一次调用后发生,因此第一次调用没有问题,但之后的所有调用都有可能触发异常

这是意料之中的。这是一个数据检索。这些总是会遇到外部异常。不管这个函数是围绕一个文件访问还是一个覆盖地球一半的网络操作,这都无关紧要——这两种情况都有潜在的外部异常


当然,特定的异常仍然很奇怪。

我没有指出的一点是,当执行
InternetOpen
时,我通过
InternetSetStatusCallback
立即将句柄分配给状态回调,只需执行
InternetSetStatusCallback(句柄,回调方法);
,显然发生的是GC收集委托是因为它被认为没有被使用,请注意,当
InternetQueryDataAvailable
被称为STATUS
INTERNET\u STATUS\u RECEIVING\u RESPONSE
INTERNET\u STATUS\u RESPONSE\u RECEIVED
时,确实会被传递到回调中,因此,我不确定GC收集委托的原因,但这是null ref的原因。
InternetQueryDataAvailable
并没有像一些人怀疑的那样引发异常。
这个问题的解决方案是创建一个委托被分配到的字段,就像GC不会收集它一样,因为容纳它的类始终是活动的,并且从不超出范围。

我猜这意味着没有设置句柄。但是,如果显示内部异常和stacktrace(基本上是exception.ToString()的结果),这将非常有用。我经常链接两篇关于异常处理的文章,这可能值得一读:|@Christopher
\u handle
IntPtr
,即使它是零,1)由于CheckHandle而引发自定义异常,2)如果
IntPtr
不可为null,则不可能出现null ref异常,即使问题出在
\u handle
上而不是它,如果它指向一个有效的http请求数据文件,
InternetQueryDataAvailable
返回一个布尔值,指示它是否成功完成,并且不应该抛出异常,特别是不受管理的c类异常。但是如果InPtr的值为null呢?我有点生疏了,但是IIRC一个指向所有“0”的指针是一种非引用的空值设置方式。a是否尝试解析_handle后面的实例,然后不抛出null引用异常?null引用异常可能来自InternetQueryDataAvailable本身,可能是因为句柄非空但无效。@RaymondChen如我所写:
请注意,调用InternetQueryDataAvailable后引发的异常仅发生在第一次调用之后,第一次调用成功,不,我不调用
InternetCloseHandle
,在此之后,我调用
InternetReadFile
,然后循环回
InternetQueryDataAvailable
,直到查询返回值为false或字节数为零为止,直到句柄关闭,所以不,句柄在整个过程中都是有效的。但是,如
InternetQueryDataAvailable
文档中所述:
如果当前没有可用数据,且尚未到达文件末尾,则请求将等待数据可用。
。另外,非托管代码不能抛出托管异常,唯一可以抛出的是COM导入的东西,而且仍然只能抛出类型为
ComException
@VincentBree的异常:即使在等待时,它也只能等待超时发生或确认连接断开。在这种情况下,继续等待,而不是以例外结束是个坏主意。如果你想否决这个答案,请提供一个更好的答案,或者评论一下你决定否决这个答案的原因。请注意,这样的评论:
这不是一个好答案,但我自己没有答案
不是一个好借口。