c# - (Pause) Stop download without dropping connection -
i want able pause download. can stop them dropping existing connections.
what i'm referring similar what's described here: https://superuser.com/questions/170509/whats-the-difference-in-using-pause-stop-in-%c2%b5torrent
my download class:
public class download { public event eventhandler<downloadstatuschangedeventargs> downloadstatuschanged; public event eventhandler<downloadprogresschangedeventargs> downloadprogresschanged; public event eventhandler downloadcompleted; public bool stop = true; // default stop true public void downloadfile(string downloadlink, string path) { stop = false; // set bool false, everytime method called long existinglength = 0; filestream savefilestream; if (file.exists(path)) { fileinfo fileinfo = new fileinfo(path); existinglength = fileinfo.length; } if (existinglength > 0) savefilestream = new filestream(path, filemode.append, fileaccess.write, fileshare.readwrite); else savefilestream = new filestream(path, filemode.create, fileaccess.write, fileshare.readwrite); var request = (httpwebrequest)httpwebrequest.create(downloadlink); request.proxy = null; request.addrange(existinglength); try { using (var response = (httpwebresponse)request.getresponse()) { long filesize = existinglength + response.contentlength; //response.contentlength gives me size remaining downloaded bool downloadresumable; // need sending empty progress if ((int)response.statuscode == 206) { console.writeline("resumable"); var downloadstatusargs = new downloadstatuschangedeventargs(); downloadresumable = true; downloadstatusargs.resumesupported = downloadresumable; ondownloadstatuschanged(downloadstatusargs); } else // server supports partial content lose ability send partial content(weird behavior) , download lose resumability { console.writeline("resume not supported"); existinglength = 0; var downloadstatusargs = new downloadstatuschangedeventargs(); downloadresumable = false; downloadstatusargs.resumesupported = downloadresumable; ondownloadstatuschanged(downloadstatusargs); // restart downloading file beginning because isn't resumable // if isn't done, method downloads file beginning , starts writing after half downloaded file, increasing filesize , corrupting downloaded file savefilestream.dispose(); // dispose object free next operation file.writealltext(path, string.empty); // clear contents of half downloaded file can't resumed savefilestream = savefilestream = new filestream(path, filemode.append, fileaccess.write, fileshare.readwrite); // reopen writing } using (var stream = response.getresponsestream()) { byte[] downbuffer = new byte[4096]; int bytesize = 0; long totalreceived = bytesize + existinglength; var sw = new stopwatch(); sw.start(); while ((bytesize = stream.read(downbuffer, 0, downbuffer.length)) > 0) { savefilestream.write(downbuffer, 0, bytesize); totalreceived += bytesize; var args = new downloadprogresschangedeventargs(); args.bytesreceived = totalreceived; args.totalbytestoreceive = filesize; float currentspeed = totalreceived / (float)sw.elapsed.totalseconds; args.currentspeed = currentspeed; if (downloadresumable == true) { args.progresspercentage = ((float)totalreceived / (float)filesize) * 100; long bytesremainingtobereceived = filesize - totalreceived; args.timeleft = (long)(bytesremainingtobereceived / currentspeed); } else { //args.progresspercentage = unknown; //args.timeleft = unknown; } ondownloadprogresschanged(args); if (stop == true) return; } sw.stop(); } } var completedargs = new eventargs(); ondownloadcompleted(completedargs); savefilestream.dispose(); } catch (webexception e) { string filename = system.io.path.getfilename(path); console.writeline(e.message); savefilestream.dispose(); return; //not needed because last line of method, let's keep here } } public void stopdownload() { stop = true; } protected virtual void ondownloadstatuschanged(downloadstatuschangedeventargs e) { eventhandler<downloadstatuschangedeventargs> handler = downloadstatuschanged; if (handler != null) { handler(this, e); } } protected virtual void ondownloadprogresschanged(downloadprogresschangedeventargs e) { eventhandler<downloadprogresschangedeventargs> handler = downloadprogresschanged; if (handler != null) { handler(this, e); } } protected virtual void ondownloadcompleted(eventargs e) { eventhandler handler = downloadcompleted; if (handler != null) { handler(this, e); } } } public class downloadstatuschangedeventargs : eventargs { public bool resumesupported { get; set; } } public class downloadprogresschangedeventargs : eventargs { public long bytesreceived { get; set; } public long totalbytestoreceive { get; set; } public float progresspercentage { get; set; } public float currentspeed { get; set; } // in bytes public long timeleft { get; set; } // in seconds }
can me this?
note: can resume downloads, that's not want, if wondering.
in code (you should copy question, way), have loop reads bytes stream. have flag stop loop.
you exact same thing except pausing instead of stopping. flag, need know when resume, need loop wait on. 1 neat way lock (mutex).
i don't know c# can't give working code, here pseudocode it. pointer the reference docs, looks semaphoreslim simplest thing suitable purpose.
bool stop = false bool paused = false semaphoreslim pauselock = new semaphoreslim(1) method download(): while (stuff read): read stream write file if stop: break // nothing if not paused, or block if paused pauselock.wait() pauselock.release() method stop(): stop = true self.unpause() // stop waiting on lock if needed method pause() if not paused: paused = true // note cannot block more moment // since download thread doesn't keep lock held pauselock.wait() method unpause() if paused: paused = false pauselock.release()
of course, doing may cause server drop connection (at point need resume anyway, , you'll notice after unpausing).
Comments
Post a Comment