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

本文关键字:队列 -C# 线程 | 更新日期: 2023-09-27 17:57:38

我们已经实现了一个将文件上传到box.net的队列。所有文件都已成功上载。但是,我在一周内会出现以下异常1到2次。我找不到任何原因造成这种异常。

异常消息:

线程正在中止。

异常来源:

mscorlib

异常StackTrace:

在System.Threading.Monitor.OjWait(布尔exitContext,Int32毫秒超时,对象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.netAPI WebApp.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);
        }
    }
}     

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

基本上,ThreadAbortException的意思正是:您的线程收到了一个杀死自己的外部信号。现在ThreadAbortException有点特殊,因为它无法处理。它只是不断地终止你的线程,每次你抓住它时都会重新思考自己http://ericlippert.com/2009/03/06/locks-and-exceptions-do-not-mix/详细信息。

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

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

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

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