0

Hi guys just wondering if somebody could help me try and correctly thread my application, I am constantly hitting an hurdle after another, I have never been to clued up on threading in applications. I have tryed following this http://www.developerfusion.com/code/4654/asynchronous-httpwebrequest/ tutorial.

basically I'm just trying to stop my request from hanging my application

public class Twitter
{
    private const string _username = "****",
        _password = "****";

    private WebResponse webResp;

    public string getTimeLine()
    {
        Thread thread = new Thread(new ThreadStart(TwitterRequestTimeLine));
        thread.IsBackground = true;
        thread.Start();

        using (Stream responseStream = webResp.GetResponseStream())
        {
            //
            using (StreamReader reader = new StreamReader(responseStream))
            {
                return reader.ReadToEnd();
            }
        }
    }

    private void TwitterRequestTimeLine()
    {
        string aUrl = "http://168.143.162.116/statuses/home_timeline.xml";
        HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create(aUrl);
        SetRequestParams(request);  
        request.Credentials = new NetworkCredential(_username, _password);
        //WebResponse tempResp = request.GetResponse();
        ThreadState state = new ThreadState();
        IAsyncResult result = request.BeginGetResponse(new AsyncCallback(???), ???);

    }



      private static void SetRequestParams( HttpWebRequest request )
  {
      request.Timeout = 500000;
      request.Method = "POST";
      request.ContentType = "application/x-www-form-urlencoded";
      request.UserAgent = "AdverTwitment";
  }
}
}

anyone help would be greatly appricated

Andreas Bonini
  • 44,018
  • 30
  • 122
  • 156
Matthew Deloughry
  • 292
  • 2
  • 7
  • 25

4 Answers4

8

You really don't need to thread HttpWebRequest.

When you use BeginGetResponse() and EndGetResponse() with HttpWebRequest, it already uses a background thread for you in order to work asynchronously. There is no reason to push this into a background thread.

As for usage: The help for HttpWebRequest.BeginGetResponse demonstrates a complete, asynchronous request.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
2

If this is a WinForms app, the easiest way to keep the GUI responsive while executing the WebRequest is to use a BackgroundWorker component. Drop a BackgroundWorker on your form and call its RunWorkAsync() method. Put the code to execute the WebRequest and read the Response in the DoWork event handler.

bpsilver
  • 141
  • 1
  • 5
0

Try using an AsyncCallback like Rubens suggested but have the callback call into a separate method to load the data to its destination. If the getTimeline method doesn't return immediately it will cause the application to hang, because the UI Thread is what is running the request itself.

If you use a separate AsyncCallback to be called after the request is done and have it load the data then the method will return immediately and your UI thread can do other things while it waits.

Stephan
  • 5,430
  • 2
  • 23
  • 31
-1

What about this:

private string getTimeLine()
{
    string responseValue = "";
    string aUrl = "http://168.143.162.116/statuses/home_timeline.xml";
    AutoResetEvent syncRequest = new AutoResetEvent(false);
    WebRequest request = WebRequest.Create(aUrl);
    request.Method = "POST";
    request.BeginGetResponse(getResponseResult =>
    {
        HttpWebResponse response = 
            (HttpWebResponse)request.EndGetResponse(getResponseResult);
        using (StreamReader reader = 
           new StreamReader(response.GetResponseStream()))
        {
            responseValue = reader.ReadToEnd();
        }

        syncRequest.Set();
    }, null);

    syncRequest.WaitOne();
    return responseValue;
}

EDIT: Ok, I tried to keep a method returning a string, that's why I used AutoResetEvent; If you use a BackgroundWorker, you'll get notified when your data is available:

BackgroundWorker worker = new BackgroundWorker();
string responseValue = "";
worker.RunWorkerCompleted += (sender, e) =>
{
    // update interface using responseValue variable
};
worker.DoWork += (sender, e) =>
{
    string aUrl = "http://168.143.162.116/statuses/home_timeline.xml";
    WebRequest request = WebRequest.Create(aUrl);
    // .. setup
    using(StreamReader reader = 
      new StreamReader(request.GetResponse().GetResponseStream()))
        responseValue = reader.ReadToEnd();
};
worker.RunWorkerAsync();
Rubens Farias
  • 57,174
  • 8
  • 131
  • 162
  • I have tried this, it's seems faster but It still seems to cause my application to hang and show "not responding" – Matthew Deloughry Dec 23 '09 at 17:03
  • 1
    That is just wrapping the async call in an resetevent to make it synchronous. – Stephan Dec 23 '09 at 17:06
  • I'm trying the edited version, and sorry if I'm missing the obvious here but how would I do send this back to update a richtextbox on a diffrent form? sorry once again guess spent to much time staring at code today – Matthew Deloughry Dec 23 '09 at 18:07
  • Inside that RunWorkerCompleted event, you can do `YourRichTextBox.Text = responseValue`; I'm not sure if you'll need to call a Invoke, as you're in a separate thread. – Rubens Farias Dec 23 '09 at 19:57