WebService调用异常:线程被中止

4

最近我们在每晚向支付服务器发送数据的ASP.NET webservice中遇到了System.Threading.ThreadAbortExceptions异常。

这个webservice是一个标准的.asmx页面,由另一个客户端调用。

在页面内部,我有一个foreach循环,遍历数据库中的多个支付行:

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循环内的代码继续执行。
这是GetPagePost方法。
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有关。 谢谢 /Jens
3个回答

4

我有类似的问题。 我认为IIS终止了您的线程,因为执行时间太长。 从您的描述“我有一个foreach循环,遍历数据库中的许多付款行”,您可以重构您的应用程序以逐个处理每一行。 创建一个webmethod将行发送到客户端,然后让客户端逐个迭代交易并在不同的webmethod中处理它们。 然后可以处理发生的异常并继续执行。 您甚至可以使用Parallel.ForEach同时处理多个。


3
最近我遇到了一个与web服务相关的问题,通过在web.config文件的</system.web>标签中添加以下代码解决了该问题:<httpRuntime executionTimeout="600"/>。 600是指asp.net关闭之前等待的秒数,默认为110秒。 这里有更好的解释。

0

经过一些研究和尝试:

  1. 尝试在应用程序池中添加自定义帐户
  2. 尝试通过从官方微软网站运行NetFxRepairTool exe来修复.net框架
  3. 尝试添加httpRuntime和targetFramework="4.5"(这对我有效 targetFramework="4.5"

httpRuntime targetFramework="4.5" maxRequestLength="4000" executionTimeout="45"

参考:http://dotnetvisio.blogspot.com/2013/07/solution-for-thread-being-aborted-call.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接