问题描述
最近,我们从 ASP.NET 网络服务获取 System.Threading.ThreadAbortExceptions,该服务每晚都将数据发布到支付服务器.
Recently we've been getting System.Threading.ThreadAbortExceptions from an ASP.NET webservice that posts data to a payment server each night.
网络服务是一个标准的 .asmx 页面,可以从另一个客户端调用.
The webservice is a standard .asmx page that gets called from another client.
在页面内,我有一个 foreach 循环,它遍历数据库中的许多付款行:
Inside the page I have a foreach loop that iterates through many payment rows in a database:
foreach (var obtRow in readyToBeCaptured)
{
try
{
status = dibs.GetPagePost(...);
// handle status here
}
catch (ThreadAbortException tex)
{
SingletonLogger.Instance.Error(string.Format("Transactionhandler - Could not Capture, Thread was aborted. {0}", tex.Message), tex);
}
catch (Exception ex)
{
SingletonLogger.Instance.Error(string.Format("Transactionhandler - Could not Capture, statuscode: {0}, message: {1}.", status, ex.Message), ex);
}
}
奇怪的是,当发生此错误时,我从 catch(ThreadAbortException tex) 块中获得了一个日志条目,但随后代码中断并在调用树更靠后的另一个 try catch 块中被捕获.理想情况下,我会让 foreach 循环中的代码继续
The strange thing is I get a log entry from catch(ThreadAbortException tex) block when this error occurs, but then the code breaks out and is caught in another try catch block further up the call tree. Ideally I would have the code inside the foreach loop to continue
这是 GetPagePost 方法
This is the GetPagePost method
private bool GetPagePost(string url, NameValueCollection nameValueCollection, string userName, string password)
{
WebClient client = new WebClient();
if (userName != "")
{
client.Credentials = new NetworkCredential(userName, password);
}
foreach (string str in nameValueCollection.AllKeys)
{
this._callCollection.Add(str, nameValueCollection[str]);
}
StringBuilder builder = new StringBuilder();
builder.Append("DIBS.NET/1.2.0 ( ");
builder.Append("OS ").Append(Environment.OSVersion.Platform).Append(" ").Append(Environment.OSVersion.Version).Append("; ");
builder.Append(".NET CLR ").Append(Environment.Version).Append("; ");
builder.Append("User ").Append(Environment.UserName).Append("; ");
builder.Append("Domain ").Append(Environment.UserDomainName).Append("; ");
builder.Append(" ) ");
client.Headers.Add("User-Agent", builder.ToString());
try
{
byte[] bytes = client.UploadValues(url, "POST", nameValueCollection);
this._httpStatus = 200;
this._httpBody = Encoding.UTF8.GetString(bytes);
return true;
}
catch (WebException exception)
{
this._httpBody = exception.Message;
this._httpStatus = (int) exception.Status;
}
catch (UriFormatException exception2)
{
this._httpBody = exception2.Message;
this._httpStatus = -9999;
}
catch (Exception exception3)
{
this._httpBody = exception3.Message;
this._httpStatus = -99999;
}
return false;
}}
为什么会发生此错误,如何防止代码跳出 foreach 循环?我一直在查看 StackOverflow 上的其他一些帖子,但它们似乎与我不使用的 Reponse.Redirect 的用法有关.
Why is this error occuring and how can I prevent the code from breaking out of the foreach loop?I've been looking at a few other posts here on StackOverflow but they seem to relate to the usage of Reponse.Redirect which I don't use.
谢谢
/詹斯
推荐答案
我有类似的问题.我认为 IIS 正在终止您的线程花费太长时间.根据您的描述我有一个循环遍历数据库中的许多付款行",您可以重构您的应用程序以单独处理每一行.创建一个 webmethod 将行发送到客户端,然后让客户端一次迭代一个事务并在不同的 webmethod 中处理它们.然后您可以处理发生的异常并继续进行.您甚至可以使用 Parallel.ForEach 一次处理多个
I have a similar issue. I think IIS is terminating your thread for taking too long. From your description "I have a foreach loop that iterates through many payment rows in a database", you may be able to restructure your app to process each row individually. Create a webmethod to send the rows to the client, then have the client iterate the transactions one at a time and process them in a different webmethod. Then you can handle exceptions that occur and keep going. You may even be able to process many at once using Parallel.ForEach
这篇关于WebService 调用异常:线程被中止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!