AnswerBun.com

WebRequest.GetResponseAsync throws uncatchable exception

Writing a small Xamarin Forms Android app in VS 2019. I have a simple async routine that checks for the existence of a file on a web server. This routine is called 3 times in a loop to try to overcome any transient network problems that may be encountered.

private async Task <BoolResult> CloudFileExistsAsync(string cloudFile, NetworkCredential creds)
{
    DebugPrint("CloudFileExistsAsync(file, creds) entered, for " + cloudFile);

    BoolResult ret = new BoolResult(false);

    WebRequest req = WebRequest.Create(cloudFile);

    req.Timeout = NetworkTimeout;
    req.Method = "HEAD";

    //if we weren't passed creds, create them now
    if (creds == null)
        creds = GetNetworkCreds(false);

    req.Credentials = creds;

    HttpWebResponse response = null;

    try
    {
        response = (HttpWebResponse)(await req.GetResponseAsync());
        ret.Result = true;
    }
    catch (Exception ex)
    {
        if (ex.Message.Contains("(404)"))
        {
            ret.Message = _FNF_Message;
            DebugPrint("'" + cloudFile + "' doesn't exist: " + ex.Message);
        }
        else
        {
            ret.Message = ex.Message;
            DebugLogException(ex, "trying to check exitance of '" + cloudFile + "'");
        }
    }
    finally
    {
        response?.Close();
        response?.Dispose();
    }

    DebugPrint("CloudFileExistsAsync(file, creds) exiting, ret = " + ret);

    return ret;

}

Note 1: BoolResult is a simple struct that has a bool and a string, so the caller can distinguish between a "file not found" exception (which may be expected) and any other "real" exceptions. The caller breaks out of its loop if the result is FNF.

Note 2: My test for "file not found" is admittedly crude; I simply did not see a way to determine same through a status code or what have you. I’d appreciate any guidance on a better way to determine FNF.

The routine generally works fine. But when debugging on an Android phone that has both wireless and mobile data turned off (to simulate a network problem), the routine works as expected the first time it’s run (a "NameResolutionFailure" exception is caught on the call to req.GetResponseAsync).

But on the second time through, the app crashes on that statement (req.GetResponseAsync), with the following debug output:

11-01 08:25:11.579 F/ ( 9983): * Assertion at
/Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mono/mini/debugger-agent.c:4660,
condition is_ok (error)' not met, function:get_this_async_id, Could not execute the method because the containing type 'System.Runtime.CompilerServices.AsyncTaskMethodBuilder1[T_REF]’, is
not fully instantiated. assembly: type: member:(null) 11-01 08:25:11.580 F/libc ( 9983): Fatal signal
6 (SIGABRT), code -1 (SI_QUEUE) in tid 10061 (Thread Pool Wor), pid
9983 (oft.cryptovault)

[note: cryptovault (last word of the debug output) is the name of the app]

I’m at a a loss here – I have no idea why this happens or what I can do about it; any advice would be appreciated.

=====================

20201105 update: I tried using HttpClient instead of WebRequest, per suggestion from @Leo Zhu – MSFT. Modified code follows.

private async Task<BoolResult> CloudFileExistsHttpClientAsync(string cloudFile, NetworkCredential creds)
{
    DebugPrint("CloudFileExistsHttpClientAsync entered for '" + cloudFile + "'");
    BoolResult ret = new BoolResult(false);

    HttpClientHandler handler = null;
    HttpClient client = null;
    HttpRequestMessage request = null;
    HttpResponseMessage response = null;

    try
    {
        handler = new HttpClientHandler { Credentials = creds };
        client = new HttpClient(handler);
        client.Timeout = new TimeSpan(0, 0, (int)(NetworkTimeout / 1000));
        request = new HttpRequestMessage(HttpMethod.Head, cloudFile);
        response = await client.SendAsync(request);

        DebugPrint("CloudFileExistsHttpClientAsync status code =" + response.StatusCode);

        switch(response.StatusCode)
        {
            case HttpStatusCode.OK:
                ret.Result = true;
                break;

            case HttpStatusCode.NotFound:
                ret.Message = _FNF_Message;
                break;

            default:
                ret.Message = response.StatusCode.ToString();
                break;
        }

    }
    catch (Exception ex)
    {
        DebugLogException(ex, "CloudFileExistsHttpClientAsync trying to check exitance of '" + cloudFile + "'");
        ret.Message = ex.Message;
    }
    finally
    {
        handler?.Dispose();
        client?.Dispose();
        request?.Dispose();
        response?.Dispose();
    }

    DebugPrint("CloudFileExistsHttpClientAsync exiting, ret = " + ret);
    return ret;
}

Pretty much the same result: first time through I get a "No such host is known" exception (as expected), and the second time I get a crash on the line:

response = await client.SendAsync(request)

Got the following debug log output:

11-05 10:46:51.370 F/ (14819): * Assertion at
/Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mono/mini/debugger-agent.c:4568,
condition `array->len == 1′ not met 11-05 10:46:51.370 F/libc
(14819): Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 14869
(Thread Pool Wor), pid 14819 (oft.cryptovault)

To see if I get a crash when running the routine a second time after the first time succeeds, I turned on Mobile data and forced a failure on the first time through (by setting ret.Result=false, even though the client.SendAsync call succeeded), and found no problem the second time through.

I am certainly puzzled … thoughts anyone?

Stack Overflow Asked by Blaise on December 29, 2020

0 Answers

Add your own answers!

Related Questions

Anomalous scanf behaviour in C

3  Asked on November 17, 2021 by parth-sarthi-sharma

     

Stop message box on a given situation Excel VBA

1  Asked on November 17, 2021

   

Is there any way to cast timedelta64 to int64 in numba?

2  Asked on November 17, 2021 by anton-philippoff

       

How do I make certain command arguments?

1  Asked on November 16, 2021 by yeti

     

Why does Vec expect &T as the argument to binary_search?

1  Asked on November 16, 2021 by grexis

 

Is it possible to hide data in a bitmap using LockBits?

1  Asked on November 16, 2021 by jeremy-james

       

Repeated filtering on Spark Dataframe?

2  Asked on November 16, 2021 by jeff-gong

     

Can Excel VSTO add-ins call Excel web add-ins?

1  Asked on November 16, 2021 by eli-chen

   

Python List: Replace Double Quotes with Single Quotes

3  Asked on November 16, 2021 by dataplumber

       

Ask a Question

Get help from others!

© 2022 AnswerBun.com. All rights reserved.