I have a component in my Windows Phone 8 app (let's call it RequestSender), which contains a queue of requests, as well as a Thread (let's call it SenderThread), which reads the queue (blocks on Dequeue), and sends the requests using HttpWebRequest.
The HttpWebRequest inside the SenderThread's method is done in a way that simulates a synchronous call, like so:
_requestWaitHandle.Reset();
IAsyncResult respResult = webReq.BeginGetResponse(GetResponseStreamCallback, null);
_requestWaitHandle.Wait();
HttpWebResponse response = webReq.EndGetResponse(respResult) as HttpWebResponse;
The only thing which the callback method does here is setting the _requestWaitHandle (which is a ManualResetWaitHandleSlim by the way).
All this works fine, except for the situation, when I try to send a "goodbye" request when the app is being closed after the user presses the "Back" hardware button.
I tried to simply enqueue the "goodbye" request in Application_Closing method, and then call a "Stop" on RequestSender. The Stop method would signal the thread that it should exit (by setting an appropriate flag), and then call Join() on the thread.
The SenderThread should finish processing the web request, check the "stop" flag, and simply exit. That's the theory.
In practice, the "goodbye" request gets enqueued, starts being processed, but the HttpWebRequest simply hangs on BeginGetResponse and never exits. What may be causing this?
In one of the answers to the following question: Question about HttpWebRequest it's stated, that "The HttpWebRequest use UI thread to process a request, don't ask me why.". Is this true? How can I avoid this and simply make the web request? Do I need to use something else than HttpWebRequest for this?
I needed the exact same thing as you and I tested everything in the platform, but only sockets got the job done.
If you want to try your luck with sockets - here's what I used (just delete the JSON-related stuff). And you'll also need this library.
The usage is something like this:
var http = new HttpSocketConnection();
var postBody = new HttpPostBodyBuilder.*Body();
// Here you set some parameters
using (var bodyStream = postBody.PrepareData()) {
var req = new HttpMessage.Request(bodyStream, "POST");
req.ContentLength = bodyStream.Length;
req.ContentType = postBody.GetContentType();
// send request
var response = http.Send(url, req);
}
Hope this helps. :)
P.S. The code is far from perfect, but it did what I needed, and you know the old saying: "If something's not broken, don't fix it". :)