views:

51

answers:

1

I don't really understand the flow/workings of async methods. I have created a WebRequest that posts data to the server. It contains alot more code than if I used normal methods.

I noticed in all callbacks, I get the request from result.AsyncState. Also say just to write to the request stream, I need to have 1 callback (reqCB) ... Its so confusing. I wonder how they map out to activities in real life?

private void Button_Click(object sender, RoutedEventArgs e)
{
    var req = (HttpWebRequest)WebRequest.Create("http://localhost/php/upload.php");
    req.Method = "POST";
    req.ContentType = "application/x-www-form-urlencoded";

    req.BeginGetRequestStream(new AsyncCallback(ReqCB), req);
}

private void ReqCB(IAsyncResult result)
{
    var req = (HttpWebRequest)result.AsyncState;
    using (var reqStream = req.EndGetRequestStream(result)) {
        var writer = new StreamWriter(reqStream);
        writer.Write("foo=bar&baz=12");
        writer.Flush();
    }
    req.BeginGetResponse(new AsyncCallback(ResCB), req);
}

private void ResCB(IAsyncResult result)
{
    var req = (HttpWebRequest)result.AsyncState;

    var res = req.EndGetResponse(result);
    using (var resStream = res.GetResponseStream()) {
        var reader = new StreamReader(resStream);
        resStream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(ReadCB), req);
        _dispatcher.Invoke(new Action(delegate
        {
            txt1.Text = res.ContentLength.ToString();
        }));
    }
}
+2  A: 

It may help to think of a list which you've handed to someone. Each step takes lots of time, so they forget what the next step is before they're done. So, they reach into their pocket, pull out the list, and realize what to do next.

The IAsyncResult has an general AsyncState property so it can be used by many different types of callback arrangements. This is why you need to cast the result.

John Fisher
I wonder if writing to the request stream is like uploading and reading the response stream is downloading? but the thing is I only `flush` the data once, thats when I finish the upload/writing of values. and when I read, I have a "full" `resStream` already?
jiewmeng
BeginGetRequestStream() sort of starts the "upload" of the request. You provide more information when writing to the request stream. Flushing that just finishes writing to the stream. When you call BeginGetResponse() the request is completely sent to the server and it waits for the server to respond. The server handles any relevant flushing and you just get a stream representing the complete "downloaded" response.
John Fisher