Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient.PostAsJsonAsync crashing without throwing exception

I have an ASP.NET MVC app with WebAPI controllers, and a console app that uses these controllers. The console app runs from a scheduled task and fetches data from remote sources, parses it, and posts it to the MVC app before exiting.

This works well for several of the controllers, but one of the calls is crashing the console app without throwing an exception. The caller code which is used for all the controllers:

    public async Task<string> Post<T>(string urlRoot, string url, T data)
    {
        var result = "";
        try
        {
            var httpClient = GetHttpClient(urlRoot);
            var response = await httpClient.PostAsJsonAsync(url, data); // Exits here
            if (response.IsSuccessStatusCode)
            {
                result = await response.Content.ReadAsAsync<string>();
            }
        }
        catch (Exception e)
        {
            Debug.WriteLine(e.ToString());
        }
        return result;
    }

The program exits when calling await httpClient.PostAsJsonAsync(url, data). Using breakpoints, neither the catch block nor the if statement are reached. The call is being made however, as the web API controller is being called with the correct data.

The programs share the same code for the T being passed across the API call.

From the output window:

The program '[9640] ProgramName.vshost.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).

I was wondering whether the size of the posted data could be a problem, but I've not found any documentation stating size limits.

So my questions are:

  1. What could be causing the console app to prematurely exit?
  2. How can I detect this and prevent the program exiting?
like image 246
harriyott Avatar asked Apr 16 '13 08:04

harriyott


2 Answers

One of possible problems, that you just don't await execution of Post method. Here is simplified version of what i am talking about:

    static void Main(string[] args)
    {
        Action testAction = async () =>
        {
            Console.WriteLine("In");
            await Task.Delay(100);
            Console.WriteLine("First delay");
            await Task.Delay(100);
            Console.WriteLine("Second delay");
        };
        testAction.Invoke();
        Thread.Sleep(150);
    }

testAction will be aborted on second await Task, and console exits with 0 code. And output will be:

   In
   First delay
   Press any key to continue . . .

In my case, i would just add Console.ReadKey() call at the end of Main method. In your case something different might be required

like image 179
Uriil Avatar answered Oct 20 '22 10:10

Uriil


Please take a look at this question witch enumerates some Exceptions you need to handle:

.NET Global exception handler in console application

Application.ThreadException += MYThreadHandler;

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

Also consider this aproach for Task Exceptions:

static void Main(string[] args)
{
    Task<int> task = new Task<int>(Test);
    task.ContinueWith(ExceptionHandler, TaskContinuationOptions.OnlyOnFaulted);
    task.Start();
    Console.ReadLine();
}

static int Test()
{
    throw new Exception();
}

static void ExceptionHandler(Task<int> task)
{
    var exception = task.Exception;
    Console.WriteLine(exception);
}

You can find more detail in one of the answers of this question:

catch exception that is thrown in different thread

like image 32
csharpwinphonexaml Avatar answered Oct 20 '22 09:10

csharpwinphonexaml