HttpClient.PostAsJsonAsync崩溃而不抛出异常

时间:2013-04-16 08:55:09

标签: c# asp.net-web-api

我有一个带有WebAPI控制器的ASP.NET MVC应用程序,以及一个使用这些控制器的控制台应用程序。控制台应用程序从计划任务运行,从远程源获取数据,解析它,并在退出之前将其发布到MVC应用程序。

这适用于多个控制器,但其中一个调用正在崩溃控制台应用程序而不会抛出异常。用于所有控制器的调用者代码:

    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;
    }

调用await httpClient.PostAsJsonAsync(url, data)时程序退出。使用断点,既未达到catch块也未达到if语句。然而,正在进行调用,因为正在使用正确的数据调用Web API控制器。

程序共享通过API调用传递的T的相同代码。

从输出窗口:

  

程序'[9640] ProgramName.vshost.exe:Managed(v4.0.30319)'已退出,代码为0(0x0)。

我想知道发布数据的大小是否有问题,但我没有找到任何说明大小限制的文档。

所以我的问题是:

  1. 可能导致控制台应用程序过早退出的原因是什么?
  2. 如何检测到此情况并阻止程序退出?

5 个答案:

答案 0 :(得分:2)

可能存在的一个问题,即你没有await执行Post方法。这是我所说的简化版本:

    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将在第二个等待任务中止,并且控制台以0代码退出。输出将是:

   In
   First delay
   Press any key to continue . . .

在我的情况下,我只会在Main方法结束时添加Console.ReadKey()调用。在您的情况下,可能需要不同的东西

答案 1 :(得分:1)

请查看这个问题,列举一些您需要处理的例外情况:

.NET Global exception handler in console application

Application.ThreadException += MYThreadHandler;

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

还要考虑任务异常的这个方法:

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);
}

您可以在此问题的答案中找到更多详细信息:

catch exception that is thrown in different thread

答案 2 :(得分:0)

  1. 一旦你点击等待控制权将被返回给Post的来电者。

  2. 不要在post方法中等待,而是从返回的任务中使用ContinueWith,例如:Task continuation on UI thread或等待返回的任务:http://msdn.microsoft.com/en-gb/library/dd537610.aspx

答案 3 :(得分:0)

我建议您进行测试,看看JSON.Net序列化程序是否能够序列化您的类型。

答案 4 :(得分:0)

&#34;退出代码0&#34;意味着程序优雅地退出。因此,可能是Post<T>的呼叫者甚至是呼叫者以上的呼叫者确定是时候结束该节目了。如果您熟悉WinDbg等调试工具,可以在ntdll函数中设置本机断点以进一步诊断案例,但通常只需要查看代码库。