views:

69

answers:

2

All, I am trying to cancel two concurrent HttpWebRequests using a method similar to the code below (shown in pseudo-ish C#).

The Main method creates two threads which create HttpWebRequests. If the user wishes to, they may abort the requests by clicking a button which then calls the Abort method.

private Thread first;
private Thread second;
private string uri = "http://somewhere";

public void Main()
{
  first = new Thread(GetFirst);
  first.Start();

  second = new Thread(GetSecond);
  second.Start();

  // Some block on threads... like the Countdown class
  countdown.Wait();
}

public void Abort()
{
  try
  {
    first.Abort();
  }
  catch { // do nothing }

  try
  {
    second.Abort();
  }
  catch { // do nothing }
}

private void GetFirst(object state)
{
  MyHandler h = new MyHandler(uri);
  h.RunRequest();
}

private void GetSecond(object state)
{
  MyHandler h = new MyHandler(uri);
  h.RunRequest();
}

The first thread gets interrupted by a SocketException:

A blocking operation was interrupted by a call to WSACancelBlockingCall

The second thread hangs on GetResponse().

How can I abort both of these requests in a way that the web server knows that the connection has been aborted?, and/or, Is there a better way to do this?

UPDATE

As suggested, a good alternative would be to use BeginGetResponse. However, I don't have access to the HttpWebRequest object - it is abstracted in the MyHandler class. I have modified the question to show this.

public class MyHandler
{
  public void RunRequest(string uri)
  {
    HttpWebRequest req = HttpWebRequest.Create(uri);
    HttpWebResponse res = req.GetResponse();
  }
}
+2  A: 

Hi,

Use BeginGetResponse to initiate the call and then use the Abort method on the class to cancel it.

http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest_methods.aspx

I believe Abort will not work with the synchronous GetResponse:

http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.abort.aspx

If you have to stick with the synchronous version, to kill the situation, all you can do is abort the thread. To give up waiting, you can specify a timeout:

http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.timeout.aspx

If you need to kill the process, I would argue launching it inside a new AppDomain and dropping the AppDomain when you want to kill the request; instead of aborting a thread inside your main process.

Adam
Adam - Could you elaborate on your comment "I believe Abort will not work with the synchronous GetResponse"? Where do you find that?
Joe
It wasn't explicitly mentioned, but the sentence: "The Abort method will synchronously execute the callback specified to the BeginGetRequestStream or BeginGetResponse methods if the Abort method is called while either of these operations are outstanding." led me to imply that it was only valid on those methods. Also, unless you do a cross-thread call into your HttpWebRequest object, you won't be able to call Abort because it will currently be blocked on GetResponse.
Adam
+2  A: 

A ThreadAbortException is highly non-specific. HttpWebRequest already supports a way to cancel the request in a predictable way with the Abort() method. I recommend you use it instead.

Note that you'll still get a WebException on the thread, designed to tell you that the request got aborted externally. Be prepared to catch it.

Hans Passant