Skip to main content

Microsoft Silverlight

Answered Question HttpWebRequest - receiving stream before it's completed. Should it work?RSS Feed

(0)

plafond444
plafond444

Member

Member

9 points

22 Posts

HttpWebRequest - receiving stream before it's completed. Should it work?

...because it works on a .Net console application. On my console app, I receive data every 10 sec (see my httphandler code, it's just a loop with Thread.Sleep(10000)). But in my SL app, it all arrives after 50 sec (once completed).

Here is the code... Same method in both apps... except for the "Console.WriteLine(..."

public void DownloadTest()
{
     string url = "http://localhost:3583/_testerweb/test.clbk";
     AutoResetEvent autoEvent = new AutoResetEvent(false);
     HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
     req.BeginGetResponse(arResponse =>
     {
          try
          {
               using (HttpWebResponse svrResp = req.EndGetResponse(arResponse) as HttpWebResponse)
               {
                    using (StreamReader sr = new StreamReader(svrResp.GetResponseStream()))
                    {
                         String outputData = "";
                         int bsize = 256;
                         Char[] buffer = new Char[bsize];
                         int nbByte = sr.Read(buffer, 0, bsize);
                         while (nbByte > 0)
                         {
                              outputData =
new String(buffer, 0, nbByte);
                              Console.WriteLine(outputData);
                              nbByte = sr.Read(buffer, 0, bsize);
                         }
                    }
               }
          }
          finally
          {
               autoEvent.Set();
          }
     },
"");
     autoEvent.WaitOne();

}

...and from the HttpHandler that writes to the string:

public void ProcessRequest(HttpContext context)
{
     int nb = 5;
     while (nb > 0)
     {
          context.Response.Write(
"status : "+nb);
          context.Response.Flush();
          nb--;
          Thread.Sleep(10000);
     }
     context.Response.Write(
"ALL DONE");
     context.Response.End();
}

It cannot be easier... Either it's a bug or it's a constraint on Silverlight version?

Thanks for your feebacks!

johnnystock
johnnystock

Contributor

Contributor

2295 points

362 Posts

Silverlight MVP

Re: HttpWebRequest - receiving stream before it's completed. Should it work?

Not a bug but a constraint in Silverlight.  Silverlight is asynchronous only so it's basically all or nothing.

John Stockton
Microsoft Silverlight MVP and RIA Developer at Ascentium
Co-Author of Silverlight 2 in Action

plafond444
plafond444

Member

Member

9 points

22 Posts

Re: HttpWebRequest - receiving stream before it's completed. Should it work?

Thanks John... Asynchronous, yes but still... do you mean the same kind of contraint as in Microsoft.XMLHTTP where readyState.INTERACTIVE is not working Smile? I mean Mozilla's XMLHttpRequest used in async mode can receive the stream before it's completed, why not HttpWebRequest?

pbromberg
pbromberg

Contributor

Contributor

2114 points

368 Posts

Re: HttpWebRequest - receiving stream before it's completed. Should it work?

What John means is that in Silverlight, WebClient and HttpWebRequest ONLY work in asynchronous mode. In order to get your results, you must do so inside the callback method.

plafond444
plafond444

Member

Member

9 points

22 Posts

Re: HttpWebRequest - receiving stream before it's completed. Should it work?

But if the asynchronous mode is the problem, why does it work in my console app? It's probably not the same assembly code (System.Net.dll), but since HttpWebRequest.BeginGetResponse's nature is to process the request asynchronously, shouldn't it produce the same result on both environments?

 

pbromberg
pbromberg

Contributor

Contributor

2114 points

368 Posts

Re: HttpWebRequest - receiving stream before it's completed. Should it work?

No. HttpWebRequest or WebClient implementations in the Silverlight CLR are NOT the exact equivalents of the full .NET Framework implementations.

You have to remember, when you create a Silverlight application you are compiling your code against the Silverlight CLR, which is a subset of the .NET Framework that is designed to install and run on the client, in the web browser, on the client machine. These classes have been created to work *like* their full framework counterparts, but to run in the Silverlight framework which is designed to download, install, and run on the client in the browser itself.

In other words, there is no such thing as a "Console App" in Silverlight.

 

Ola Karlsson
Ola Karl...

Member

Member

127 points

25 Posts

Re: HttpWebRequest - receiving stream before it's completed. Should it work?

There's actually new functionality in Beta 2 which might do something along the lines of what you're after.

From the HttpWebRequest.AllowReadStreamBuffering Property documentation

"When AllowReadStreamBuffering is true, the data is buffered in memory so it is ready to be read by the application.

The AllowReadStreamBuffering property affects when the callback from BeginGetResponse method is called. When the AllowReadStreamBuffering property is true, the callback is raised once the entire stream has been downloaded into memory. When the AllowReadStreamBuffering property is false, the callback is raised as soon as the stream is available for reading which may be before all data has arrived."

 

------------------------------------------------------------------------------------

<sarcasm>
Don't worry too much about marking my posts as anwers, I'm not just doing it for the points ;)</sarcasm>

http://weblogs.asp.net/olakarlsson/

plafond444
plafond444

Member

Member

9 points

22 Posts

Re: HttpWebRequest - receiving stream before it's completed. Should it work?

I never said I was running a Silverlight console app.... I have one web project for my httphandler, one "console app" project (full framework) and one Silverlight project. I just use the exact same DownloadTest() method (see the original post) in both projects.

As far as I know, the only implementation difference using HttpWebRequest (full vs SL) was a threading issue (running on UI thread), not an asynchronous one.

plafond444
plafond444

Member

Member

9 points

22 Posts

Re: HttpWebRequest - receiving stream before it's completed. Should it work?

Thanks Ola, exactly what I thought when I found AllowReadStreamBuffering yesterday... I was going to reply to my own thread... but unfortunately, it doesn't seem to affect anything. I set it to "false" just before the req.BeginGetResponse(... call.

As you mentioned, it should allow the stream to be readable right after BeginGetResponse...  as the "full framework" one does (by default).

Does someone has a working example with HttpWebRequest.AllowReadStreamBuffering set to false?    

Thanks 

plafond444
plafond444

Member

Member

9 points

22 Posts

Answered Question

Re: HttpWebRequest - receiving stream before it's completed. Should it work? ... yes

Yes, it does work!  (...but I still don't know if it's a bug or "by design")

So, what was wrong with my initial sample code? The first difference between the full framework and SL when calling BeginGetResponse is AllowReadStreamBuffering. As mentioned by Ola, HttpWebRequest.AllowReadStreamBuffering (new in Beta 2) needs to be set to false (default is true). That will work but there is a catch (the second difference between "full framework" and Silverlight for BeginGetResponse). Why was it waiting until the end of the stream to step in BeginGetResponse then? 4kb...(4096 I suppose).

HttpWebRequest.AllowReadStreamBuffering set BrowserHttpWebRequest._allowBufering variable. This is used in Completed, Failed and Progress methods.... Progress is the one.... if _allowBuffering==true, call the Callback param... and this event is raised by InternalWebRequest object... nothing I can get more from there... I haven't been able to find where, but I suppose that before Progress can be called, there is a conditional statement that verifies that the stream is greater then 4kb....

So in my sample code, I was writing 5 times "status : XX" to the response stream (and was getting the result as one string instead of five small strings). The resulting string was far from 4kb (but this works in my app console).... If I send a 4kb chunk first, then the following "status : XX" are received every 10 sec as expected.

Obviously, sending an initial 4kb chunk is applicable only when you control the server part... at least now you know that you will need to have received 4kb from the server before AllowReadStreamBuffering take effect.

Cheers!

 

cagdasgerede
cagdasge...

Member

Member

11 points

23 Posts

Re: Re: HttpWebRequest - receiving stream before it's completed. Should it work? ... yes

Thanks for this great information. I was looking for a way to read I made a couple of posts but nobody seemed to know about this feature. Thanks for pointing out "gotchas" too on your web page. http://blog.lfdx.com/blogengine.net/post/HttpWebRequestAllowReadStreamBuffering3dfalse-Still-buffering-up-to-4kb!.aspx According to my tests, this is true for Firefox 2, 3, and IE 6,7. I would like to add that according to my experiments the first message you send is not received until the second messsage is received unless the first message size is 8KB or bigger. This is true for both Firefox and IE.

Zhi Chen
Zhi Chen

Member

Member

4 points

2 Posts

Re: Re: HttpWebRequest - receiving stream before it's completed. Should it work? ... yes

I think platond444's reply is great - very informative!!

I just discovered the initial buffering even I have the AllowReadStreamBuffering set to false.

Is there any way to disable the initial buffering. In my case I have the control over the server piece but writing 4K dummy data seems dum.

 thanks

  • Unanswered Question
  • Answered Question
  • Announcement
Microsoft Communities