gpt4 book ai didi

c# - 无法处理 ThreadAbortException

转载 作者:行者123 更新时间:2023-11-30 17:48:10 27 4
gpt4 key购买 nike

我有一个 WCF 服务,该服务接受请求并针对每个请求进行 HTTPWebRequest 调用并返回响应。我使用 BlockingCollection 来存储传入的请求,并使用一个单独的线程处理(生成 Web 请求)集合中的项目。有时 Webrequest 会返回一个 threadabortexception。我捕获它并执行 Thread.ResetAbort。但是异常向上流动并清除了 BlockingCollection。我在下面添加了代码片段。我需要找到一种方法让 foreach 循环继续,即使我遇到 threadabort 异常。

public static class YBProcessor
{
static PriorityQueue<QueuePriorityLevel, string> queue = new PriorityQueue<QueuePriorityLevel, string>();
static BlockingCollection<KeyValuePair<QueuePriorityLevel, string>> requests;
static YBProcessor()
{
requests = new BlockingCollection<KeyValuePair<QueuePriorityLevel, string>>(queue);
Task.Factory.StartNew(() => SendRequestToYB());
}
public static void AddCalcRequest(string cusip, double price, QueuePriorityLevel priority)
{
requests.Add(new KeyValuePair<QueuePriorityLevel, string>(priority, cusip + "-" + price.ToString()));
}
private static void SendRequestToYB()
{
// this is a separate thread that processes the requests as the come in.
foreach (var obj in requests.GetConsumingEnumerable())
{
try
{
var request = GetXML(obj.Value);
var response = YBClient.GetResponse(request);
//code to handle response
}
catch (ThreadAbortException ex)
{
Thread.ResetAbort();
}
catch (Exception ex)
{
}
}
}
}

//YBClient中的GetResponse方法(只是关键部分,代码无法编译)

private static String GetResponse(String text)
{
for (iTry = 0; iTry < MAX_TRY; iTry++)
{

try
{
// Create and setup request
bytes = encoding.GetBytes(text);
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "text/xml";
request.ContentLength = bytes.Length;
request.CookieContainer = cookieJar;
request.Timeout = 100 * 1000;
request.ReadWriteTimeout = 100 * 1000;

// Prepare and send data
postStream = request.GetRequestStream();
postStream.Write(bytes, 0, bytes.Length);
postStream.Close();

// Get response from server
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
reader = new StreamReader(response.GetResponseStream(), encoding);
xmlResponse = reader.ReadToEnd();
reader.Close();
break;
}
response.Close();
}
catch (ThreadAbortException ex)
{
Thread.ResetAbort();
break;
}
catch (Exception ex)
{
if (ex.GetBaseException() is ThreadAbortException)
{
Thread.ResetAbort();
break;
}
}
}
}
return xmlResponse;
}

最佳答案

如果服务本身正在调用线程中止异常那么这可能意味着服务正在关闭,在这种情况下你的线程无法继续运行(想象一个应用程序池回收),如果你想确保你的待处理请求是没有丢失,那么您可以执行以下操作之一:

1) 启动一个新的应用程序域 http://msdn.microsoft.com/en-us/library/ms173139(v=vs.90).aspx

此方法将减轻服务关闭的情况,但仍无法解决确保您的所有请求都得到处理的根本问题,因为“其他”应用程序域也可能会关闭。

2) 更好的解决方案是继续在中央数据库或文件中以序列化形式编写您的请求,并让工作人员不断弹出相同的项目,如果您想要简单,请为每个请求创建单独的文件,并且在处理后删除它们(假设您不会收到数千个请求/秒),对于更具可扩展性的解决方案,您可以使用 Redis 数据库(http://redis.io/)并使用其“列表”(队列)功能。

附言您可能希望将您的线程(任务)标记为长时间运行,如果您不这样做,它会使用不推荐用于长时间运行任务的线程池。

 Task.Factory.StartNew(Run, TaskCreationOptions.LongRunning);

关于c# - 无法处理 ThreadAbortException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23497282/

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