【问题标题】:IIS 7.5 Application Pool Recycle not letting method finishIIS 7.5 应用程序池回收不让方法完成
【发布时间】:2014-09-10 01:03:09
【问题描述】:

我有两种方法:

public void Stop(bool immediate)
{
    Logger.Log(LogLevel.Debug, "Shutdown detected. Immediate: " + immediate);
    Shutdown();
    Logger.Log(LogLevel.Debug, "Unregistering");
    HostingEnvironment.UnregisterObject(this);
}

public void Shutdown()
{
    Logger.Log(LogLevel.Debug, "Preparing to stop UploadQueue");
    IsProcessing = false;

     //Set tasks to cancel to prevent queued tasks from parsing
     _cancellationTokenSource.Cancel();

     Logger.Log(LogLevel.Debug, "Waiting for " + _workerTasks.Count + " tasks to finish or cancel.");
     //Wait for tasks to finish
     Task.WaitAll(_workerTasks.Values.ToArray());

     Logger.Log(LogLevel.Debug, "Stopped UploadQueue");
}

该类正在使用 IRegisteredObject 接口来接收关闭通知。在我的日志中,我得到了这个:

2014-07-18 15:30:55,913,DEBUG,Shutdown detected. Immediate: False
2014-07-18 15:30:55,913,DEBUG,Preparing to stop UploadQueue
2014-07-18 15:30:55,913,DEBUG,Waiting for 35 tasks to finish or cancel.
...
bunch of stuff
...
2014-07-18 15:31:28,471,DEBUG,Shutdown detected. Immediate: True
2014-07-18 15:31:28,471,DEBUG,Preparing to stop UploadQueue
2014-07-18 15:31:28,471,DEBUG,Waiting for 0 tasks to finish or cancel.
2014-07-18 15:31:28,471,DEBUG,Stopped UploadQueue
2014-07-18 15:31:28,471,DEBUG,Unregistering

为什么不是第一次到达Logger.Log(LogLevel.Debug, "Stopped UploadQueue");?它似乎确实取消了任务并让正在运行的任务完成。 (任务在运行前检查它是否被取消,否则就是这样)。

【问题讨论】:

  • 也许某些任务在第一种情况下会抛出异常?所以 Logger.Log() 方法不是这样调用的。

标签: c# asp.net iis application-pool


【解决方案1】:

来自Task.WaitAll

聚合异常:

至少有一个 Task 实例被取消 - 或 - 在至少一个 Task 实例的执行过程中引发了异常。如果任务被取消,则 AggregateException 在其 InnerExceptions 集合中包含一个 OperationCanceledException。

您正在通过_cancellationTokenSource.Cancel(); 取消您的任务,我认为这至少会导致其中一个引发异常。您可能会在更高级别的堆栈帧中捕获它并忽略它。将 Task.WaitAll 包裹在 try-catch 块中:

public void Shutdown()
{
    Logger.Log(LogLevel.Debug, "Preparing to stop UploadQueue");
    IsProcessing = false;

    //Set tasks to cancel to prevent queued tasks from parsing
    _cancellationTokenSource.Cancel();

    Logger.Log(LogLevel.Debug, "Waiting for " + _workerTasks.Count + " tasks to finish or cancel.");

     try
     {
         //Wait for tasks to finish
         Task.WaitAll(_workerTasks.Values.ToArray());

         Logger.Log(LogLevel.Debug, "Stopped UploadQueue");
     }
     catch (AggregationException e)
     {
         // Recover from the exception
     }
}

【讨论】:

  • +1 但请注意:从异常中恢复,不要忽略它。
  • @JohnSaunders 我总是尝试/捕捉/吞下,这肯定是最好的。
  • @Shawn:不,这是最糟糕的。
  • @JohnSaunders 讽刺也是最好的。
  • @Shawn:这是一个国际网站。许多读者不会知道你在讽刺。
猜你喜欢
  • 2011-03-10
  • 2023-04-07
  • 2011-09-20
  • 2011-07-26
  • 2011-11-30
  • 2012-12-04
  • 2012-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多