线程被中止-使用队列的C#

use*_*413 2 c# queue box-api

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

异常消息:

威胁已经被清除了。

异常源:

mscorlib

Exception-StackTrace:

在Box的System.Threading.Monitor.ObjWait(布尔值exitContext,Int32毫秒超时,对象obj)在Box。 C:\ Project \ BackupProjects \ BoxNetFileUpload \ Box.netAPIWebApp \ Source \ Service \ BoxService.cs:line 90中的.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);
        }
    }

}     
Run Code Online (Sandbox Code Playgroud)

Lum*_*mpN 6

基本上,ThreadAbortException的确切含义是:您的线程接收到一个外部信号来杀死自己。现在,ThreadAbortException有点特殊,因为它无法处理。每次捕获它时,它都会通过重新抛出线程来终止线程。有关详细信息,请参见http://ericlippert.com/2009/03/06/locks-and-exceptions-do-not-mix/

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

如果您绝对必须终止正在监视器上等待的线程,则有更好的方法。例如,使线程同时在多个监视器上等待:一个用于队列,另一个用于发出终止信号。然后,不要通过终止终止线程来杀死它,而只是给终止监视器脉冲,让线程自己关闭。

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