How to cancel FTP?

CyborgPrime

Member
Joined
Sep 3, 2021
Messages
18
Programming Experience
10+
Hi! I wrote a cool updater - it works fine, but I have it set to download a bunch of files from an ftp site and I want to be able to cancel it in case the user wants to abort before the ftp is done.

I have it set to do the download after I click a button. I was hoping I could have a cancel button that stops the ftp loop.

Originally I wanted the DOWNLOAD button to change to CANCEL and be active again but it turns off until it's done processing the file list.

Any suggestions?
 
Do I just check the status of the cancel button at some point during the loop and if it is clicked then do the STOP command (or whatever the cancel loop command is).
 
Is your "cool" updater written using the WinForm framework? WPF? WinUI? Xamarin?
 
Do I just check the status of the cancel button at some point during the loop and if it is clicked then do the STOP command (or whatever the cancel loop command is).
No. The first step you do, is actually make your FTP download work be done in another thread other than the current UI thread. That way you can flip the button over to say "Cancel" and you can get the events fired when the user clicks on it.

The next step is calling the appropriate method for stopping the FTP download. That will depend on which framework helper class you are using to do the FTP download, or if you wrote your own TCP client code to do the FTP download.
 
It is written with Winform

It seems the UI is "locked" while the download occurs. Do I have to make a new thread for each download request?
 
at the top of the download loop i am just check to see if a global "cancelled" variable has been set to true and if not, download the next file
but there's no way to click the cancel button bc the UI seems "locked" until the download is complete
 
at the moment i just want to get the cancel button working lol
Screenshot 2021-09-03 144707.png
 
It seems the UI is "locked" while the download occurs. Do I have to make a new thread for each download request?
That would happen if you are doing the download on the UI thread.

Please show us your code so that we can see how you are doing your download: FtpWebRequest, WebClient, etc.
 
FTP download loop:
        private void DownloadRCFiles(string[] remoteFileNames, string ftpURL,string ftpUsername, string ftpPassword)
        {

            string fileURL;
            string filePath; //encoded filename by RealmCrafter
            string localFilePath; // holds decoded path
            string localFileName; // holds decoded filename
            float updateProgress; // holds the percentage of update completed
            int remoteFileNamesLength; // holds the length if the filenames list

            remoteFileNamesLength = remoteFileNames.Length;

            for (int i = 0; i < remoteFileNamesLength; i++)
            {
                    // modify path to remote file
                    fileURL = ftpURL + "/" + remoteFileNames[i];
                   
                    // create a request for the remote file
                    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(fileURL);

                    // add credentials to the request
                    request.Credentials = new NetworkCredential(ftpUsername, ftpPassword);

                    // ask for file to be downloaded
                    request.Method = WebRequestMethods.Ftp.DownloadFile;

                    // connect to the ftp stream
                    using (Stream ftpStream = request.GetResponse().GetResponseStream())

                    // create a local file and connect a stream to its handle
                    // and copy the file from the stream to the local storage
                    using (Stream fileStream = File.Create(localFilePath+localFileName))
                    {
                        ftpStream.CopyTo(fileStream);
                    }
                    updateProgress = Convert.ToSingle(i+1) / Convert.ToSingle(remoteFileNamesLength) * 100;

                    Console.WriteLine((i+1)+" of "+ remoteFileNamesLength + " files updated ({0,5:N2}%)", updateProgress);
                }
                else
                {
                    break;
                }
            }
        }

I guess I can just do an open once before the loop starts rather than with each request - sorry this is my first FTp program
 
Last edited:
Or use the async versions of the methods of the web request.

Or use Task.Start() to simplify running code in the built in thread pools.

Or use the WebClient class async methods.

But yes, it all comes down to not doing work in the UI thread.
 
You should do some research on using async/await and then use the asynchronous methods available to you.

Instead of GetResponse you can call GetResponseAsync. You can also then call CopyToAsync, which supports cancellation, on the NetworkStream instead of CopyTo.

If you don't need the extra control a WebRequest provides, you can also forgo the extra complexity and, as suggested, use a WebClient. It has DownloadFileTaskAsync (don't use DownloadFileAsync, which uses the old asynchronous pattern) and CancelAsync methods. You can also not await the call and handle the DownloadFileCompleted event to be notified when the download is complete.
 
Back
Top Bottom