【问题标题】:Thread was being aborted - C# using queue线程被中止 - C# 使用队列
【发布时间】:2014-04-10 06:27:38
【问题描述】:

我们已经实现了一个用于将文件上传到 box.net 的队列。 所有文件均已成功上传。但是,我在一周内收到以下异常 1 或 2 次。我找不到导致此异常的任何原因。

异常消息:

线程被中止。

异常来源:

mscorlib

异常堆栈跟踪:

在 System.Threading.Monitor.ObjWait(Boolean exitContext, Int32 millisecondsTimeout, Object obj) 在 System.Threading.Monitor.Wait(对象 obj,Int32 毫秒超时,布尔 exitContext) 在 System.Threading.Monitor.Wait(对象 obj) 在 C:\Project\BackupProjects\BoxNetFileUpload\Box.netAPIWebApp\Source\Service\BoxService.cs:line 90 中的 Box.netAPIWebApp.Service.BoxService.monitorOnUploadQueue() 处

有人可以帮忙吗?

private static readonly BoxService instance = new BoxService();

private Queue<FileCabinetUploadHistory> uploadQueue = new Queue<FileCabinetUploadHistory>();


private BoxService()
{
    Thread monitorThread = new Thread(new ThreadStart(monitorOnUploadQueue));
    monitorThread.Start();
}

private FileCabinetUploadHistory RemoveFromUploadQueue()
{
    lock (uploadQueue)
    {
        return uploadQueue.Dequeue();
    }
}

private void monitorOnUploadQueue()
{
    FileCabinetUploadHistory fileCabinetUploadHistory = null;
    try
    {
        while (true)
        {
            if (uploadQueue.Count < 1)
            {
                lock (uploadQueue)
                {
                    Monitor.Wait(uploadQueue);
                }
            }
            fileCabinetUploadHistory = uploadQueue.Peek();

            if (fileCabinetUploadHistory != null)
            {
                StartFileUpload(fileCabinetUploadHistory);
            }
        }
    }
    catch (Exception exception)
    {
        log.Error("Error:--> Class name: BoxService, Method name: monitorOnUploadQueue() \n", exception);
    }
}

public void AddToUploadQueue(FileCabinetUploadHistory fileCabinetUploadHistory)
{
    lock (uploadQueue)
    {
        if (!uploadQueue.Contains(fileCabinetUploadHistory))
        {
            uploadQueue.Enqueue(fileCabinetUploadHistory);
            Monitor.Pulse(uploadQueue);
        }
    }

}     

【问题讨论】:

  • 能否贴出引发此异常的源代码?
  • 你如何使用BoxService.monitorOnUploadQueue
  • @user743414 从引发异常的 BoxService 类发布代码。
  • 当您收到此错误时,您是否知道队列中有多少项?何时以及多久调用一次 RemoveFromUploadQueue?
  • 队列中没有项目

标签: c# queue box-api


【解决方案1】:

基本上一个 ThreadAbortException 意味着:你的线程收到一个外部信号来杀死自己。现在 ThreadAbortException 有点特殊,因为它无法处理。它只是通过每次捕获它时重新抛出自身来继续终止您的线程。详情请见http://ericlippert.com/2009/03/06/locks-and-exceptions-do-not-mix/

所以现在你可能会问自己是谁发送了上面提到的外部信号。我不知道。您显示的代码不足以说明问题。但是很有可能有人仍然拥有 monitorThread 的句柄并在其上调用 thread.Abort()。您的代码库是否包含.Abort()?如果是这样,请放心,这是一个非常糟糕的主意。再次查看上面的链接了解详情。

如果您必须终止在监视器上等待的线程,有更好的方法。例如,让线程同时在多个监视器上等待:一个用于队列,一个用于发出终止信号。然后不要通过 abort 杀死线程,您只需脉冲终止监视器并让线程自行关闭。

顺便说一句,您正在以不安全的方式访问您的队列。写访问似乎处于锁定状态,但读访问(Count,Peek)不是。这不是应该使用锁定的方式,并且可能(并且最终会)发生坏事。不要这样做!请参阅http://blog.coverity.com/2014/03/12/can-skip-lock-reading-integer/ 了解原因。

【讨论】:

    【解决方案2】:

    我明白了。 当应用程序池每 29 小时回收一次时,会发生 ThreadAbortException。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 2022-01-17
      • 2011-02-01
      • 1970-01-01
      相关资源
      最近更新 更多