线程被中止-C#正在使用队列
我们已经实现了一个将文件上传到box.net的队列。 所有文件均已成功上载。但是,我在一周内会有1到2次以下异常。我找不到导致此异常的任何原因 异常消息: 线程正在中止 异常源: mscorlib 异常堆栈跟踪: 在System.Threading.Monitor.ObjWait(布尔exitContext,Int32毫秒超时,对象obj) 在System.Threading.Monitor.Wait(对象obj、Int32毫秒超时、布尔exitContext) at System.Threading.Monitor.Wait(对象obj) 在C:\Project\BackupProjects\BoxNetFileUpload\Box.netAPIWebApp\Source\Service\BoxService.cs中的Box.netAPIWebApp.Service.BoxService.monitorOnUploadQueue()处:第90行 有人能帮忙吗线程被中止-C#正在使用队列,c#,queue,box-api,C#,Queue,Box Api,我们已经实现了一个将文件上传到box.net的队列。 所有文件均已成功上载。但是,我在一周内会有1到2次以下异常。我找不到导致此异常的任何原因 异常消息: 线程正在中止 异常源: mscorlib 异常堆栈跟踪: 在System.Threading.Monitor.ObjWait(布尔exitContext,Int32毫秒超时,对象obj) 在System.Threading.Monitor.Wait(对象obj、Int32毫秒超时、布尔exitContext) at System.Thread
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);
}
}
}
private static readonly-BoxService实例=new-BoxService();
专用队列uploadQueue=新队列();
私人信箱服务()
{
线程monitorThread=新线程(新线程开始(monitorOnUploadQueue));
monitorThread.Start();
}
私有文件CabinetUploadHistory RemoveFromUploadQueue()
{
锁定(上载队列)
{
返回uploadQueue.Dequeue();
}
}
专用void监视器onuploadqueue()
{
FileCabinetUploadHistory FileCabinetUploadHistory=null;
尝试
{
while(true)
{
if(uploadQueue.Count<1)
{
锁定(上载队列)
{
Monitor.Wait(上传队列);
}
}
fileCabinetUploadHistory=uploadQueue.Peek();
if(fileCabinetUploadHistory!=null)
{
StartFileUpload(fileCabinetUploadHistory);
}
}
}
捕获(异常)
{
log.Error(“错误:-->类名:BoxService,方法名:monitorOnUploadQueue()\n”,异常);
}
}
public void AddToUploadQueue(FileCabinetUploadHistory FileCabinetUploadHistory)
{
锁定(上载队列)
{
如果(!uploadQueue.Contains(fileCabinetUploadHistory))
{
Enqueue(fileCabinetUploadHistory);
Monitor.Pulse(上传队列);
}
}
}
基本上,ThreadAbortException意味着:您的线程接收到一个外部信号以终止自身。现在ThreadAbortException有点特殊,因为它无法处理。它只是不断地终止你的线程,每次你抓到它时,它都会重新旋转它自己。有关详细信息,请参阅
所以现在你可能会问自己是谁发送了上面提到的外部信号。我不知道。您显示的代码不足以说明。但很有可能有人仍然拥有monitorThread的句柄,并对其调用thread.Abort()。您的代码库是否包含.Abort()
?如果是这样,请放心,这是一个非常糟糕的主意。有关详细信息,请再次参阅上面的链接
如果您必须终止等待监视器的线程,有更好的方法。例如,让线程同时在多个监视器上等待:一个用于队列,另一个用于发出终止信号。然后,您只需脉冲终止监视器,让线程自行关闭,而不是通过中止终止终止线程
顺便说一下,您正在以不安全的方式访问队列。写访问似乎处于锁定状态,但读访问(计数、窥视)不处于锁定状态。这不是应该使用的锁定方式,坏事情可能(并且最终会)发生。别这样!看看原因。我明白了。
ThreadAbortException发生在应用程序池每29小时回收一次时。您可以发布引发此异常的源代码吗?如何使用
BoxService.monitorOnUploadQueue
?@user743414发布来自BoxService类的代码,该类引发异常。收到此消息时,您知道队列中有多少项吗错误?何时以及多久调用一次RemoveFromUploadQueue?队列中没有项目