How to cancel Upload/Download

Mar 13, 2013 at 3:18 PM
Edited Mar 13, 2013 at 3:35 PM
Hi,

I am using a switch to break the while loop while downloading and i get an error "The specified network name is no longer available". if i try to download again i get the same error.

here is my code:
    void testftp()
    {
        try
        {
            UpdateLabel("Connecting to FileShare Server");

            FtpClient ftpc = new FtpClient();
            ftpc.Host = new Uri("ftp://www.vuepointconnect.com").Host;
            ftpc.Credentials = new NetworkCredential("username", "password");
            ftpc.EncryptionMode = FtpEncryptionMode.Explicit;
            ftpc.ValidateCertificate += new FtpSslValidation(OnValidateCertificate);              

            using (Stream istream = ftpc.OpenRead("Skrillex - Cinema (Official).mp4"))
            {
                 FileStream fileoutput = new FileStream(@"C:\TempTest\Skrillex - Cinema (Official).mp4", FileMode.Create, System.IO.FileAccess.Write);

                 try
                 {
                        double DownloadFileSize = ftpc.GetFileSize("Skrillex - Cinema (Official).mp4");
                        UpdateSetProgress((int)DownloadFileSize);
                        sw.Start();
                        string strSpeed = "";
                        double bytesRead = 0;
                        byte[] buffer = new byte[604800];
                        int len;
                        while ((len = istream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            if (CancelAction)  
                            {  
                                ftpc.Disconnect();
                                //ftpc.Dispose();
                                break;  
                            }                       
                            bytesRead+=len;
                            UpdateBytesLabel( ConvertBytesToMegabytes((long)bytesRead).ToString("0.00") + " MB of ", ConvertBytesToMegabytes((long)DownloadFileSize).ToString("0.00") + " MB");
                            fileoutput.Write(buffer, 0, len);
                            if (strSpeed != (Convert.ToDouble(bytesRead) / 1024 / sw.Elapsed.TotalSeconds).ToString("0"))
                                strSpeed = (Convert.ToDouble(bytesRead) / 1024 / sw.Elapsed.TotalSeconds).ToString("0.00") + " kb/s";
                            double dblSpeed = (Convert.ToDouble(bytesRead) / 1024 / sw.Elapsed.TotalSeconds);
                            double TimeRemaining = (DownloadFileSize - bytesRead) / dblSpeed;
                            UpdateSpeedLabel(strSpeed, TimeRemaining);
                            UpdateProgress((int)bytesRead);
                        }
                  }
                  finally
                  {
                    if (fileoutput != null)
                    {
                      fileoutput.Close();
                      fileoutput = null;
                    }
                    if (istream != null)
                    {
                      istream.Close();
                    }
                    //ftpc.Disconnect();
                    //ftpc.BeginDisconnect();
                    //ftpc.Dispose();
                    //ftpc = null;
                  }
              }
        }
        catch(Exception ex)
        {
            int a = 1;
        }
    }
i have been trying a few things here to dispose but i'm down to my last hair :)
any help would be great.

looking at the stacktrace, it's coming from ftpclient line 1034 CloseDataStream(FtpDataStream stream). something with the GetReply i think. not sure.
Coordinator
Mar 13, 2013 at 3:53 PM
When you disconnect / abort you need to disconnect the stream, not the client. Unless you set FtpClient.EnableThreadSafeDataChannels = false, the client is cloned and a new connection is made and tied to the data stream you're downloading from. When that data stream is closed, it closes the associated client. In other words, ftpc.Disconnect() when CancelAction is true does nothing for closing the data stream in progress. You should call istream.Close() instead. When you close a download before it's completed expect a FtpCommandException() to be thrown. The server will send a 4xx reply which you need to catch and discard when explicitly aborting / interrupting the transfer.

Modify your code accordingly and let me know where you stand on this problem.
Mar 13, 2013 at 4:15 PM
Hi and thanks for the reply.

i added istream.Close() to the cancelaction and i still get the same. i think is somehow coming from trying to close the stream. i've been thinking that maybe i'm not cleaning up properly before closing it.

it seems that this exception stops me from re-downloading. i appreciate your advice
Mar 14, 2013 at 4:24 AM
Seems to be solved now. Not entirely sure how but !!!!!
    public void FTPDownload(string FileName, string Path)
    {
        try
        {
            IsDownload = true;
            HaveResetFTP = false;
            UpdateConnectionLabel(ConnectionMessage);
            FtpClient ftpClient = NewFTPClient();

                        using (Stream istreamDownload = ftpClient.OpenRead(FileName))
            {
                                FileStream fileDownload = new FileStream(Path + "\\" + FileName, FileMode.Create, System.IO.FileAccess.Write);
                                try
                {
                    FTPDownloadFileSize = ftpClient.GetFileSize(FileName);
                    SetProgressBarMax((int)FTPDownloadFileSize);
                                        FTPStopWatch.Start();
                                            byte[] BufferIn = new byte[FTPChunkSize];
                                            int BufferLength;
                                        while ((BufferLength = istreamDownload.Read(BufferIn, 0, BufferIn.Length)) > 0)
                                        {
                        //The action has been cancelled by the user
                        if (CancelFTPAction)
                                            {  
                            ResetFTPInfo();
                                            ftpClient.EnableThreadSafeDataConnections = false;
                                            istreamDownload.Close();
                                                    break;  
                                            }  

                                                FTPBytesRead += BufferLength;

                                                fileDownload.Write(BufferIn, 0, BufferLength);

                                                //Update Output
                        UpdateFTPInfo();

                        //Reset on Complete
                        if (FTPBytesRead == FTPDownloadFileSize)
                        {
                            ResetFTPInfo();
                        }
                                    }
                        }
                        finally
                        {
                    if (fileDownload != null)
                            {
                                  fileDownload.Close();
                            }
                            if (istreamDownload != null)
                            {
                                      istreamDownload.Close();
                            }
                            ftpClient.Disconnect();
                    ResetFTPInfo();
                        }
                    }
        }
        catch
        {
            ResetFTPInfo();
            //MessageBox.Show(ex.Message);
        }
    }
Must be the order now disposing correctly. cheers and thanks