11

我有一个带有 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 控制器。

这些程序共享相同的代码,以便T通过 API 调用传递。

从输出窗口:

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

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

所以我的问题是:

  1. 什么可能导致控制台应用程序过早退出?
  2. 如何检测到这一点并防止程序退出?
4

5 回答 5

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 . . .

就我而言,我只会Console.ReadKey()在 Main 方法的末尾添加 call 。在您的情况下,可能需要一些不同的东西

于 2014-04-25T06:09:10.623 回答
1

请看一下这个问题,它列举了一些您需要处理的异常:

.NET 控制台应用程序中的全局异常处理程序

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

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

捕获在不同线程中抛出的异常

于 2014-04-29T18:40:52.660 回答
0

I would suggest testing to see if the JSON.Net serializer is capable of serializing your type.

于 2013-04-16T14:15:02.917 回答
0
  1. 一旦你点击等待控制将返回给 Post 的调用者。

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

于 2013-04-16T12:35:58.817 回答
0

“exited with code 0”表示程序正常退出。因此,可能是调用者的调用者Post<T>甚至上层调用者确定是时候结束程序了。如果你熟悉 WinDbg 等调试工具,你可以在 ntdll 函数处设置原生断点来进一步诊断案例,但通常你只需要查看你的代码库。

于 2014-04-23T02:51:29.720 回答