views:

168

answers:

2

I have a simple one-way web service in my C# .NET web application. I need to download an image from a given URL and save it to my server.

However, every OTHER time I call the service it works perfectly. The other times I get a "Thread was being aborted" exception on the webClient.DownloadFile line.

I've read that WebClient uses httpWebRequest which requires access to HttpContext.Current. Is this true? If so, why can it access it, literally, every other time?

I've tried adding the following lines before my call:

WebService service = new WebService();
HttpContext.Current = service.Context;

But it doesn't make a difference.

I ran the service 10 times, here are the results:

1: Success

2: Exception: Thread was being aborted. Stack Trace: at System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.Net.WebClient.DownloadBitsState.RetrieveBytes(Int32& bytesRetrieved) at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream, CompletionDelegate completionDelegate, AsyncOperation asyncOp) at System.Net.WebClient.DownloadFile(Uri address, String fileName)...

3: Success

4: Exception: Thread was being aborted. Stack Trace: at System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.Net.WebClient.DownloadBitsState.RetrieveBytes(Int32& bytesRetrieved) at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream, CompletionDelegate completionDelegate, AsyncOperation asyncOp) at System.Net.WebClient.DownloadFile(Uri address, String fileName)...

5: Success

6: Exception: Thread was being aborted. Stack Trace: at System.Net.WebClient.DownloadBitsState.SetResponse(WebResponse response) at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream, CompletionDelegate completionDelegate, AsyncOperation asyncOp) at System.Net.WebClient.DownloadFile(Uri address, String fileName) ...

7: Success

8: Exception: Thread was being aborted. Stack Trace: at System.Net.WebClient.DownloadBitsState.SetResponse(WebResponse response) at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream, CompletionDelegate completionDelegate, AsyncOperation asyncOp) at System.Net.WebClient.DownloadFile(Uri address, String fileName) ...

9: Success

10: Exception: Thread was being aborted. Stack Trace: at System.Net.WebClient.DownloadBitsState.SetResponse(WebResponse response) at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream, CompletionDelegate completionDelegate, AsyncOperation asyncOp) at System.Net.WebClient.DownloadFile(Uri address, String fileName)...

Is there any way to make this work??

EDIT: In response to question regarding posting code: There is not much to post. It is all quite simple.

[WebService(Namespace = "http://nerdliness.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService()]
[System.ComponentModel.ToolboxItem(false)]      
public class FileProcessor : System.Web.Services.WebService
{

    [WebMethod]
    [SoapDocumentMethod(OneWay = true)]
    public void ParseFile(String urlOfFileToGrab, String destinationPath)
    {
          try
          {
               WebClient client = new WebClient();
               client.DownloadFile(urlOfFileToGrab, destinationPath);
               client.Dispose();
           }
           catch (Exception ex)
           {  
              //Log it
           }
    }
}
A: 

Without seeing any code, it sounds like you are not properly disposing of resources that you are creating/consuming within your webservice. Thus, it works, then crashes (aborts the thread which disposes of everything), then it works again.

EDIT:

A few other things to think about/look at. 1) I have never used the one-way binding before, does this work when you don't have that set. 2) Are you calling these too fast? Meaning, it the download/save done by the time you call the method again? 3) In your web.config, are your timeouts and max download sizes set large enough to allow you to download/transfer files?

<system.web>
    <httpRuntime executionTimeout="600" maxRequestLength="2048000" />
</system.web>

That's all that I can think of, if it doesn't help, perhaps someone else has ran into this problem before. According to Google, your about the only one :)

Tommy
Thank you for the response. I have now posted the code. Is there anything else I should be doing to wrap things up in there???
Pam Bullock
A: 

OK, huge turn of events and I apologize for not researching as thoroughly as I should have before posting (although I have been working on this for two days...) That httpContext thing was a long wild goose chase :(

The code I posted above was a simplified version of what I'm really working with (dumb, I know, I'm sorry). But it prompted me to try that simplified version which works!

My issue is now:

I have an object with a list of my own (not System.Web.Drawing) ImageFile objects. Before I use the webClient to download new files, I make a call that deletes all of the current ImageFile files from the object first. This call loops through the list and for each ImageFile does the following:

 try
            {
                File.Delete(lowResFilePath);
                File.Delete(hiResFilePath);
            }
            catch (Exception ex0)
            { }

            try
            {
                if (Directory.GetFiles(hiResFilePath.Substring(0, hiResFilePath.LastIndexOf("\\"))).Length <= 0)
                    Directory.Delete(hiResFilePath.Substring(0, hiResFilePath.LastIndexOf("\\")));
            }
            catch (Exception ex0)
            { }

When I use the above method, the service errors out as mentioned in the original post. However, if I comment out the following lines:

                //try
            //{
            //    if (Directory.GetFiles(hiResFilePath.Substring(0, hiResFilePath.LastIndexOf("\\"))).Length <= 0)
            //        Directory.Delete(hiResFilePath.Substring(0, hiResFilePath.LastIndexOf("\\")));
            //}
            //catch (Exception ex0)
            //{ }

Everything works fine!!

Those lines simply check a folder that contained one of the files just deleted. If that folder is now empty, I want to delete it.

Again, my apologies for leading you nice people on my own wild goose chase. But do you have any ideas why this might be happening? Or how I can successfully delete the directory if empty without the webclient line throwing a threadabortexception??

Thanks :)

Pam Bullock
Does this happen in it's own thread or a callback? It's hard guess what is going on without the whole context. And what line does the error occur on?
Arkain