IIS black-holing Task.Factory.StartNew异常

时间:2012-07-19 20:12:14

标签: c# iis task-parallel-library

我正在使用II6。我有一个我认为有异常的方法(LogMessageToSIFDB),

Task.Factory.StartNew(() => LogMessageToSIFDB(inClientID, tmpByte, Modified, SIF_MessageID, SIF_TimeStamp));

方法很简单

  1. 连接到数据库
  2. 致电Sproc
  3. 关闭连接
  4. 数据库连接现在可以正常工作。我遇到的问题是如果发生异常,任何地方都无法记录。

    如果我更改逻辑流程,则不会调用SProc并且不会将任何内容记录到事件或任何内容

    1. 抛出新的ApplicationException(“来自LogMessageToSIFDB()的Hello”);
    2. 连接到数据库
    3. 致电Sproc
    4. 关闭连接
    5. 简而言之,这不会导致某些事情被记录下来。

      Task.Factory.StartNew(() => { throw new ApplicationException("Hello from LogMessageToSIFDB()"); });
      

      这是我正在尝试做的事情。我在DLL中实现了这个代码,它实现了Engineering给我的接口。它们传入一个XML消息流。我需要修改那条消息。我还需要记录原始消息。

      将消息记录到数据库只会导致IIS线程阻塞更长时间,所以我想我只是创建一个任务并让它运行异步。如果呼叫暂时不起作用,我真的不在乎,但如果我一直在调试当前的问题,我需要看到一条错误信息。

      我希望任务中未处理的异常会在事件日志中出现,但我什么都没看到。

      异步日志记录不是必需的,但它是首选。最糟糕的情况是删除任务并让它同步运行。

1 个答案:

答案 0 :(得分:1)

对于Task s,期望您将以某种方式观察Task的异常:使用Wait()Result(抛出异常,包含在AggregateException)中或直接访问其Exception属性。

如果你不这样做并且Task被垃圾收集,它的终结器将抛出异常,这将使整个过程失效(尽管.Net 4.5改变了,终结器将不再抛出) 。但你必须记住,GC不是确定性的,Task只能在很长一段时间后收集,这很可能是你没有看到任何东西的原因。

你应该做的是以某种方式观察异常。如果您想异步执行此操作,可以将ContinueWith()OnlyOnFaulted一起使用。但更简单的方法是使用普通try - catch

Task.Factory.StartNew(() =>
{
    try
    {
        LogMessageToSIFDB(inClientID, tmpByte, Modified, SIF_MessageID, SIF_TimeStamp));
    }
    catch (Exception ex)
    {
        // perform your logging here
    }
});