BeginRead & ThreadPool.QueueUserWorkItem

  • Thread starter Thread starter Lloyd Dupont
  • Start date Start date
L

Lloyd Dupont

I want to do background download of a file.

II'm curious to know about other people idea on the following topic:

I found using the stream.BeginRead() method quite ackward compare to simple
used directly
ThreadPool.QueueUserWokrItem() myself (or using a new thread for that
matter)

what do you think?
 
Hi Lloyd,

The way i see it. The Begin/End way of doing it is for easy-as-it-gets
async operations where you don't want the overhead of a making a
thread. Using a Thread is the next step up and using the ThreadPool is
the most complete solution.

Given that, I would chose the solution that best fit the situation.
Library code -> ThreadPool, Quick Utility -> Begin/End

Just my 2 pence,
Jan
 
mmhh... I think I should take the pain to experiment a few BeginRead sample,
just to see...
it's just I'm so used to create Thread, it's seems much simple to me, not
too mention the way you could do anonymous method in 2.0!..
 
mmhh... I think I should take the pain to experiment a few BeginRead sample,
just to see...
it's just I'm so used to create Thread, it's seems much simple to me, not
too mention the way you could do anonymous method in 2.0!..

Generally, .NET classes that offer a BeginXXX method as an asynchronous
alternative to the XXX mehtod do so because the implementation of their
BeginXXX method is more efficient than creating a thread and calling the
XXX method within it.

I'm not too sure of what happens with the Stream class but if you take the
Socket class for instance, it has a Connect and a BeginConnect methods.
What takes time when connecting to a server is not the processing that you
need to do but the time it takes for your packets to travel across the
network. If you were to create a new thread and simply call the Connect
method within it, then your new thread, which would have required some time
to be created, would basically sit there, waiting for the server answer to
arrive, doing absolutely nothing for most of its lifetime. A big waste of
ressources. If you had called the BeginConnect method instead, this method
would have had issued the required commands to your network adapter and
returned immediately afterwards without waiting for the answer to arrive.
No time waisted in creating a thread. When the server answer would have had
arrived, the network adapter would have notified the Framework in some way
(an interuption maybe), and the Framework would then have taken a thread
from the threadpool (once again, not need to create a new thread) to
execute your callback method. More efficient than manually creating a new
thread that would just wait for something to happen. Actually, once you
played a bit with the BeginXXX methods, you'll find them easier to use than
always having to create your own threads. They also allow you to keep a
consistent coding style when doing asynchronous operations since they all
work in the same way (return an IAsyncResult, take an AsyncCallback and a
state object as parameters).
 
Thanks for this long explanation ;-)
Certainly once I will have play with them I will get use to them ;-)
Anyway for my purpose of downloading a file file I really doubt BeginRead()
will be easier to write, care to make a sample simpler than this one? (with
BeginRead(), I dare you! ;-)

public class UpdateForm : Form
{
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
Stop();
}

bool downloading; // for stopping;
public void DoDownload()
{
downloading = true;
WebRequest wr = WebRequest.Create("http://something");
public new Thread(delegate()
{
int nRead;
byte[] buf = new byte[1<<12];
try
{
int count = 0;
using(WebResponse resp = wr.GetResponse())
using(FileStream output = new FileStream("dstfile.bin",
FileMode.Open, FileAccess.Write))
while(!IsDisposed && downloading && (nRead =
s.Read(buf, 0, buf.Length))>0)
{
output.Write(buf, 0, nRead);
count += nRead;
if(!IsDisposed)
BeginInvoke(new MethodInvoker(delegate(){
progressBar.Value = count; }));
}

if(downloading && !IsDisposed)
BeginInvoke(new MethodInvoker(delegate()
{
MessageBox.Show("Download completed successfully",
"Download");
});
}
catch(IOException ioe)
{
if(!IsDisposed)
BeginInvoke(new MethodInvoker(delegate()
{
MessageBox.Show(ioe.Message, "Problem");
});
}
}).Start();
}
public void Stop()
{
downloading = false;
Thread.MemoryBarrier();
}
}
 
Back
Top