简体   繁体   中英

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?

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

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

  1. Once you hit await control will be returned to the caller of Post.

  2. Rather than have await in the post method, use ContinueWith from the returned task, something like: Task continuation on UI thread or Wait on the returned task: http://msdn.microsoft.com/en-gb/library/dd537610.aspx

我建议测试一下JSON.Net序列化程序是否能够序列化你的类型。

"exited with code 0" means the program exited gracefully. Thus, it might be the caller of Post<T> or even above callers determine that it was time to end the program. If you are familiar with debugging tools such as WinDbg, you can set native breakpoints at ntdll functions to further diagnose the case, but normally you just need to review your code base.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM