Vincent Bree
Vincent Bree

Reputation: 435

When calling wininet functions random NullReferenceException occur

Not sure why but at random when calling the function InternetQueryDataAvailable a null ref exception occurs for no apparent reason sins non of the arguments which it accepts can be 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);

Here is the exception:

enter image description here

And no, CheckHandle() isn't the culprit as all it does is check if _handle is zero or not, aka invalid.

Also, if not this then after downloading all the data and attempting to close the application, sins I set it up so all the handles close before the app closes, the call to InternetCloseHandle throws the null ref exception even tho, just like with InternetQueryDataAvailable, non of the arguments are nullable sins all it accepts is a single IntPtr:

[DllImport(Dlls.Wininet, SetLastError = true)]
public static extern bool InternetCloseHandle([In] IntPtr hInternet);

Am not sure what's going on because, on rare occasions everything works fine and I am able to download all the data and close the handle without a random exception being thrown.

For those wondering what the function with InternetCloseHandle looks like, it's just:

public void Dispose()
{
    if (_handle != IntPtr.Zero)
    {
        if (!WinINet.InternetCloseHandle(_handle))
        {
            throw new Win32Exception();
        }
        _handle = IntPtr.Zero;
    }

}

Note that the exception which is thrown after calling InternetQueryDataAvailable only occurs after the first call, so the first is fine but all the ones after have a chance of triggering the exception.

Upvotes: 1

Views: 231

Answers (2)

Vincent Bree
Vincent Bree

Reputation: 435

A thing I didn't point out, which was the cause of this null ref exception, was that when InternetOpen is performed, I instantly assign the handle to a status callback via InternetSetStatusCallback by just doing InternetSetStatusCallback(handle, CallbackMethod);, apparently what was happening was that the GC collected the delegate because it supposedly wasn't being used, note that when InternetQueryDataAvailable is called the statuses INTERNET_STATUS_RECEIVING_RESPONSE and INTERNET_STATUS_RESPONSE_RECEIVED do get passed to the callback, so am not sure why the GC collected the delegate but, that was the cause of the null ref. It wasn't that the InternetQueryDataAvailable was throwing the exception, as some suspected. The solution for this was to create a field to which the delegate is assigned, like that the GC wont collect it due to the fact that the class housing it is always alive and is never out of scope.

Upvotes: 1

Christopher
Christopher

Reputation: 9804

Note that the exception which is thrown after calling InternetQueryDataAvailable only occurs after the first call, so the first is fine but all the ones after have a chance of triggering the exception.

This is to be expected. It is a data retreival. Those can always run into Exogenous Exceptions. It does not mater if that function wraps around a file access or a network operation going over half the planet - both of those scenarios got exogenous exception potential in spades.

Of course the specific exception is still odd.

Upvotes: 0

Related Questions