Working with very vanilla implementation of .Net Asynchronous Web
Request I found that when I have Fiddler2 enabled it appears to read
the entire data stream before calling the BeginGetResponse callback.
Below is logging info from two sessions. The difference is that with
Fiddler off the Response Callback occurs after about a half second and
with Fiddler2 on it takes about 21 seconds before the Response
callback is made leading me to believe it is buffering the stream.
With longer files being downloaded I have seen it stall for 15 minutes
before getting to the first Response Callback.
Is this expected behavior or an issue with my settings?
(Fiddler Off)
00000.008: Calling BeginGetResponse
00000.528: RespCallback
00000.533: ReadCallBack: 2601
00000.628: ReadCallBack: 4096
00000.640: ReadCallBack: 3472
...
00019.038: ReadCallBack: 1168
00019.375: ReadCallBack: 2565
00019.376: ReadCallBack: 0
00019.376: Done.
Read 1477494 bytes
(Fidder On)
00000.006: Calling BeginGetResponse
00021.837: RespCallback
00021.839: ReadCallBack: 4096
00021.840: ReadCallBack: 4096
00021.840: ReadCallBack: 4096
...
00021.870: ReadCallBack: 3472
00021.870: ReadCallBack: 242
00021.870: ReadCallBack: 0
00021.871: Done.
Read 1477494 bytes
This is the code below should it help...
===========================================================
===========================================================
===========================================================
using System;
using System.Net;
using System.IO;
using System.Text;
using System.Threading;
class WebRequest_BeginGetResponse
{
class State
{
// This class stores the state of the request.
const int BUFFER_SIZE = 4096;
public byte[] buffer;
public HttpWebRequest httpRequest;
public HttpWebResponse httpResponse;
public Stream responseStream;
public ManualResetEvent allDone;
public MemoryStream data;
public State(WebRequest webRequest, MemoryStream data)
{
this.httpRequest = (HttpWebRequest)webRequest;
this.data = data;
this.buffer = new byte[BUFFER_SIZE];
this.httpResponse = null;
this.allDone = new ManualResetEvent(false);
//this.BytesRead = 0;
}
}
static DateTime StartTime = DateTime.Now;
static string ElapsedTime()
{
TimeSpan Elapsed = DateTime.Now.Subtract(StartTime);
return String.Format("{0:00000}.{1:000}", Elapsed.Seconds,
Elapsed.Milliseconds);
}
private static void RespCallback(IAsyncResult asyncResult)
{
Console.WriteLine("{0}: RespCallback", ElapsedTime());
try
{
State state = (State)asyncResult.AsyncState;
// End the Asynchronous response.
state.httpResponse =
(HttpWebResponse)state.httpRequest.EndGetResponse(asyncResult);
// Read the response into a 'Stream' object.
state.responseStream =
state.httpResponse.GetResponseStream();
// Begin the reading of the contents of the HTML page and
print it to the console.
int bufsize = state.buffer.GetLength(0);
IAsyncResult asyncResultRead =
state.responseStream.BeginRead(state.buffer, 0, bufsize, new
AsyncCallback(ReadCallBack), state);
}
catch (WebException e)
{
Console.WriteLine("WebException raised!");
Console.WriteLine("\n{0}", e.Message);
Console.WriteLine("\n{0}", e.Status);
}
catch (Exception e)
{
Console.WriteLine("Exception raised!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
}
private static void ReadCallBack(IAsyncResult asyncResult)
{
try
{
// Result state is set to AsyncState.
State state = (State)asyncResult.AsyncState;
int lengthRead =
state.responseStream.EndRead(asyncResult);
Console.WriteLine("{0}: ReadCallBack: {1}", ElapsedTime(),
lengthRead);
if (lengthRead > 0)
{
state.data.Write(state.buffer, 0, lengthRead);
int bufsize = state.buffer.GetLength(0);
IAsyncResult asyncNext =
state.responseStream.BeginRead(state.buffer, 0, bufsize, new
AsyncCallback(ReadCallBack), state);
}
else
{
state.responseStream.Close();
state.allDone.Set();
}
}
catch (WebException e)
{
Console.WriteLine("WebException raised!");
Console.WriteLine("\n{0}", e.Message);
Console.WriteLine("\n{0}", e.Status);
}
catch (Exception e)
{
Console.WriteLine("Exception raised!");
Console.WriteLine("Source : {0}", e.Source);
Console.WriteLine("Message : {0}", e.Message);
}
}
public static bool ReadUrlToStream(string url, out MemoryStream
ms)
{
ms = new MemoryStream();
// set up the request object
try
{
Console.WriteLine("{0}: Calling BeginGetResponse",
ElapsedTime());
// create request and state objects
WebRequest webRequest = WebRequest.Create(url);
State state = new State(webRequest, ms);
// Start the Asynchronous call for response
IAsyncResult asyncResult =
state.httpRequest.BeginGetResponse(new AsyncCallback(RespCallback),
state);
// await completion
state.allDone.WaitOne();
state.httpResponse.Close();
Console.WriteLine("{0}: Done.", ElapsedTime());
// Release the resources
}
catch (WebException e)
{
Console.WriteLine(String.Format("WebException {0} - {1}",
e.Status, e.Message));
return false;
}
return true;
}
static void Main()
{
// a 1.1 MB download from Microsoft
string url = "
http://download.microsoft.com/download/5/e/
6/5e66b27b-988b-4f50-af3a-c2ff1e62180f/con-t615_wh08.pptx";
MemoryStream ms;
if (ReadUrlToStream(url, out ms))
{
Console.WriteLine(String.Format("Read {0}", ms.Length,
url));
//File.WriteAllBytes(@"c:\temp\file.bin", ms.ToArray());
}
//
// wait for a keystroke
//
//Console.WriteLine(" \nPress 'Enter' key to continue........"
//Console.ReadKey();
}
}