c# - Asynchronous download algorithm with progress value -
i made simple algorithm winrt app. having stream of class webresponse. need download file asynchronously "progresschanged" event. here method:
public async void downloadfileasync(string uri, storagefile path) { var request = webrequest.createhttp(uri); var response = await request.getresponseasync(); if (response != null) { long totalbytes = response.contentlength; long writedbytes = 0; using(var webstream = response.getresponsestream()) using (irandomaccessstream stream = await path.openasync(fileaccessmode.readwrite)) using (datawriter datawriter = new datawriter(stream)) { await task.run(() => { int b; while ((b = webstream.readbyte()) != -1) { datawriter.writebyte((byte)b); writedbytes++; if (writedbytes % (totalbytes / 100) == 0) onprogresschanged(new progresseventargs(writedbytes / (totalbytes / 100))); } }); await datawriter.storeasync(); ondownloadcomplete(new eventargs()); } } }
progresseventargs code:
public class progresseventargs : eventargs { public progresseventargs(double percentage) { percentage = percentage; } public double percentage { get; set; } }
this working. think it's should faster. sequential bytes reading slow. how can make faster. i'm beginner. please help.
reading , writing large amount of data byte byte may slow down, have millions of method calls downloading 1mb file. should use buffer instead read data in chunks:
... long totalbytesread = 0; // allocate 4kb buffer each read/write byte[] buffer = new byte[4 * 1024]; int bytesread; // read 4kb of data, check if data read while ((bytesread = webstream.read(buffer, 0, buffer.length)) > 0) { // write 4kb (or less) buffer datawriter.writebuffer(buffer.asbuffer(0, bytesread)); totalbytesread += bytesread; // todo: report progresss } ....
the optimal buffer size depends on many things, 4kb buffer should fine. here can more info.
Comments
Post a Comment