views:

188

answers:

5

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

+6  A: 

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
A: 

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
I have tried this, it's seems faster but It still seems to cause my application to hang and show "not responding"
Matthew De'Loughry
That is just wrapping the async call in an resetevent to make it synchronous.
Stephan
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 De'Loughry
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
A: 

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
+1  A: 

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
A: 

thanks guys I ended up using the idea from the comment Chris S left and bpsilver answer thanks alot for all the help!

Matthew De'Loughry