M Raymaker
M Raymaker

Reputation: 1271

WebService Call Exception: Thread was being aborted

Recently we've been getting System.Threading.ThreadAbortExceptions from an ASP.NET webservice that posts data to a payment server each night.

The webservice is a standard .asmx page that gets called from another client.

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

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

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

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.

Thanks

/Jens

Upvotes: 4

Views: 11378

Answers (3)

Manjunath Bilwar
Manjunath Bilwar

Reputation: 2353

After some RND try few things:

  1. try adding custom account in the application pool
  2. try repairing the .net framework by running the NetFxRepairTool exe from official Microsoft website
  3. try adding httpRuntime and targetFramework="4.5" (This works for me targetFramework="4.5")

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

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

Upvotes: 0

Carlos Busca
Carlos Busca

Reputation: 135

Last days I had a similar problem with a web service and solved it adding to </system.web> of web.config this line: <httpRuntime executionTimeout="600"/>. 600 is the number of seconds till is shut downed by asp.net. The default is 110 seconds. It explains here better what it does.

Upvotes: 3

jlo
jlo

Reputation: 256

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

Upvotes: 4

Related Questions