Recursive uploading files using FtpWebRequest , BackgroundWorker in C# -


using ftpwebrequest class , assign backgroundworker upload file. , working want upload files directory , sub-directory.

i have created component called - "ftpuploading" in define private void function "ftpuploading_dowork"

and same should calling windows form application... if single file in directory working file if there more 1 file , sub-directory... not work.

    private void ftpuploading_dowork(object sender, doworkeventargs e)     {             backgroundworker bw = sender backgroundworker;             ftpsettings ftpdet = e.argument ftpsettings;              string uploadpath = string.format("{0}/{1}{2}", ftpdet.host, ftpdet.targetfolder == "" ? "" : ftpdet.targetfolder + "/", path.getfilename(ftpdet.sourcefile));             if (!uploadpath.tolower().startswith("ftp://"))                 uploadpath = "ftp://" + uploadpath;             ftpwebrequest request = (ftpwebrequest)webrequest.create(uploadpath);             request.usebinary = true;             request.usepassive = ftpdet.passive;             request.method = webrequestmethods.ftp.uploadfile;             request.credentials = new networkcredential(ftpdet.username, ftpdet.password);              long filesize = new fileinfo(ftpdet.sourcefile).length;             string mfilename = new fileinfo(ftpdet.sourcefile).name;             string filesizedescription = getfilesize(filesize);             int chunksize = 4096, numretries = 0, maxretries = 50;             long sentbytes = 0;              byte[] buffer = new byte[chunksize];              using (stream requeststream = request.getrequeststream())             {                 using (filestream fs = file.open(ftpdet.sourcefile, filemode.open, fileaccess.read, fileshare.readwrite))                 {                     int bytesread = fs.read(buffer, 0, chunksize);                       while (bytesread > 0)                     {                         try                         {                             if (bw.cancellationpending)                                 return;                              requeststream.write(buffer, 0, bytesread);                             sentbytes += bytesread;                              string summarytext = string.format(mfilename + " => transferred {0} / {1}", getfilesize(sentbytes), filesizedescription);                             bw.reportprogress((int)(((decimal)sentbytes / (decimal)filesize) * 100), summarytext);                         }                         catch (exception ex)                         {                             debug.writeline("exception: " + ex.tostring());                             if (numretries++ < maxretries)                             {                                 fs.position -= bytesread;                             }                             else                             {                                 throw new exception(string.format("error occurred during upload, many retries. \n{0}", ex.tostring()));                             }                         }                         bytesread = fs.read(buffer, 0, chunksize);                       }                 }             }             using (ftpwebresponse response = (ftpwebresponse)request.getresponse())                 system.diagnostics.debug.writeline(string.format("upload file complete, status {0}", response.statusdescription));         }       public static string getfilesize(long numbytes)     {         string filesize = "";          if (numbytes > 1073741824)             filesize = string.format("{0:0.00} gb", (double)numbytes / 1073741824);         else if (numbytes > 1048576)             filesize = string.format("{0:0.00} mb", (double)numbytes / 1048576);         else             filesize = string.format("{0:0} kb", (double)numbytes / 1024);          if (filesize == "0 kb")             filesize = "1 kb";  // min.                                  return filesize;     } 

//calling function

        private void recursivedirectory(string dirpath, string uploadpath)     {         string[] files = directory.getfiles(dirpath, "*.*");         string[] subdirs = directory.getdirectories(dirpath);         foreach (string file in files)         {             if (this.ftpuploading1.isbusy)             {                // this.ftpuploading1.cancelasync();                // this.btnftp.text = "upload";                 thread.sleep(50);                 break;             }             else             {                 ftpset.targetfolder = uploadpath;                 ftpset.sourcefile = file;                 this.toolstripprogressbar1.visible = true;                 this.ftpuploading1.runworkerasync(ftpset);                 this.btnftp.text = "cancel";             }         }         foreach (string subdir in subdirs)         {             ftpclient.createdirectory(uploadpath + "/" + path.getfilename(subdir));             recursivedirectory(subdir, uploadpath + "/" + path.getfilename(subdir));         }     } 

you check isbusy after starting aync task, , if it's true, break loop of is. happening.

removing condition lead error mentioned in comments. should either wait task completed, or implement loop inside ftpuploading_dowork.

and third (and best) option use task. task supports continuewith() need.

i explain first solution here, because needs little changes on existing code. give glimpse of synchronization process. need polish code further.

you need waithandle, ftpuploading_dowork tell recursivedirectory when finished job. use manualresetevent matter. once reset manualresetevent, wait on call waitone until thread calls set on same manualresetevent.

so work, add manualresetevent class:

system.threading.manualresetevent waitforupload = new                                 system.threading.manualresetevent(false); 

change first for inside recursivedirectory:

    foreach (string file in files)     {         ftpset.targetfolder = uploadpath;         ftpset.sourcefile = file;         this.toolstripprogressbar1.visible = true;          waitforupload.reset();         this.ftpuploading1.runworkerasync(ftpset);         this.btnftp.text = "cancel";          waitforupload.waitone();         while (this.ftpuploading1.isbusy)         {             thread.sleep(100); // case if waithandle set                                // backgroundworker still busy,                                 // should not take long         }     } 

and change ftpuploading_dowork:

private void ftpuploading_dowork(object sender, doworkeventargs e) {     try     {          // existing code inside method     }         {         waitforupload.set();     } } 

Comments

Popular posts from this blog

java - activate/deactivate sonar maven plugin by profile? -

python - TypeError: can only concatenate tuple (not "float") to tuple -

java - What is the difference between String. and String.this. ? -