gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 19:26:25 25 4
gpt4 key购买 nike

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

异常消息:

Thread was being aborted.

异常来源:

mscorlib

异常堆栈跟踪:

at System.Threading.Monitor.ObjWait(Boolean exitContext, Int32 millisecondsTimeout, Object obj) at System.Threading.Monitor.Wait(Object obj, Int32 millisecondsTimeout, Boolean exitContext) at System.Threading.Monitor.Wait(Object obj) at Box.netAPIWebApp.Service.BoxService.monitorOnUploadQueue() in C:\Project\BackupProjects\BoxNetFileUpload\Box.netAPIWebApp\Source\Service\BoxService.cs:line 90

有人可以帮忙吗?

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);
}
}

}

最佳答案

基本上,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/找出原因。

关于c# - 线程被中止 - C# 使用队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22980173/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com