Task скачивания файла

204
27 декабря 2017, 18:07

Запутался в одном вопросе, просьба знающих помочь. При открытии формы проверяю, существует ли на жёстком диске файл. Если нет - качаем его из интернета. При этом на форме показывается прогресс скачивания. Тут всё нормально. Но, если закрыть форму во время скачивания файла и открыть снова, скачивание файла не начинается заново. Код такой

  private async void fPreTrain_Load(object sender, EventArgs e)
        {             
            string path = Application.StartupPath + @"\vids\warmup.mp4";
            axWindowsMediaPlayer1.URL = path;
            if (!Classes.Options.WarmupFileLoaded)
            {// Файла нет, качаем
                layoutControlItem2.Visibility = DevExpress.XtraLayout.Utils.LayoutVisibility.Always;
                string clean_path = Path.GetDirectoryName(path);
                if (!Directory.Exists(clean_path))
                    Directory.CreateDirectory(clean_path);
                try
                {
                    await Task.Run(() => Classes.HttpManager.DownloadFile(
                       "https://hardworkandsweat.com//content/videos/warmup.mp4", path, progressDownload));                  
                }
                catch
                {
                    Classes.Options.WarmupFileLoaded = false; 
                    layoutControlItem2.Visibility = DevExpress.XtraLayout.Utils.LayoutVisibility.Never;
                    if (Classes.MyForm.Show("Ошибка","Не получилось скачать файл разминки. Открыть видео в браузере?", Classes.MyForm.ftypes.Warning) == DialogResult.Yes)
                        System.Diagnostics.Process.Start("https://hardworkandsweat.com//content/videos/warmup.mp4");
                    return;
                }
                layoutControlItem2.Visibility = DevExpress.XtraLayout.Utils.LayoutVisibility.Never;
                Classes.Options.WarmupFileLoaded = true;
                axWindowsMediaPlayer1.Ctlcontrols.play();
            }   
            else       
                axWindowsMediaPlayer1.Ctlcontrols.play();
        }

update: Подебажил. Обнаружил следующее: при первом открытии формы файл качается корректно. Закрыл форму во время скачивания и открыл заново. Когда запускается метод DownloadFile, почему-то уже не получается подключиться к серверу. При этом, если прогу закрыть совсем, и открыть заново. Всё качает

public static void DownloadFile(string url,string save_to,DevExpress.XtraEditors.ProgressBarControl progress)
        {
            try
            {
                WebRequest sizeRequest = (HttpWebRequest)WebRequest.Create(url);
                sizeRequest.Method = "HEAD";
                int size = (int)sizeRequest.GetResponse().ContentLength;
                progress.Invoke(
                    (MethodInvoker)(() => progress.Properties.Maximum = size));             
                // Download the file
                HttpWebRequest httpRequest = (HttpWebRequest)
WebRequest.Create(url);
                httpRequest.Method = WebRequestMethods.Http.Get;
                HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();
                Stream ftpStream = httpResponse.GetResponseStream();
                // create and open a FileStream, using calls dispose when done
                using (var fs = File.Create(save_to))
                {
                    byte[] buffer = new byte[10240];
                    int read;
                    while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        fs.Write(buffer, 0, read);
                        int position = (int)fs.Position;
                        progress.Invoke(
                            (MethodInvoker)(() => progress.Position = position));
                        // progress.Position = position;
                    }
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }          
        }

понял в чём был косяк. поправил таким образом:

 public static class HttpManager
    {
        static WebRequest sizeRequest;
        static HttpWebRequest httpRequest;
        public static void StopDownload()
        {
            sizeRequest.Abort();
            sizeRequest = null;
            httpRequest.Abort();
            httpRequest = null;
        }              
        public static void DownloadFile(string url,string save_to,DevExpress.XtraEditors.ProgressBarControl progress)
        {
            try
            {
                sizeRequest = (HttpWebRequest)WebRequest.Create(url);
                int size = (int)sizeRequest.GetResponse().ContentLength;
                progress.Invoke(
                    (MethodInvoker)(() => progress.Properties.Maximum = size));             
                // Download the file
              httpRequest = (HttpWebRequest)
WebRequest.Create(url);
                httpRequest.Method = WebRequestMethods.Http.Get;
                HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();
                Stream ftpStream = httpResponse.GetResponseStream();
                // create and open a FileStream, using calls dispose when done
                using (var fs = File.Create(save_to))
                {
                    byte[] buffer = new byte[10240];
                    int read;
                    while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        if (progress != null)
                        {
                            fs.Write(buffer, 0, read);
                            int position = (int)fs.Position;
                            progress.Invoke(
                                (MethodInvoker)(() => progress.Position = position));
                            // progress.Position = position;
                        }
                        else
                            return;
                    }
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }          
        }

Теперь ругается на стрим когда код доходит до записи в файл, говорит что файл уже занят другим процессом. Как мне прекратить использование файла при закрытии формы?

Answer 1

Костыльно, но решил. Вот так:

 public static class HttpManager
    {
        static WebRequest sizeRequest;
        static HttpWebRequest httpRequest;
        static Stream ftpStream;
        static FileStream fs;
        public static void StopDownload()
        {
            sizeRequest.Abort();
            sizeRequest = null;
            httpRequest.Abort();
            httpRequest = null;
            if (ftpStream!=null)
            {
                ftpStream.Close();
                ftpStream = null;
            }                  
            if (fs!=null)
            {
                fs.Close();
                fs = null;
            }   
        }      
        public static void DownloadFile(string url,string save_to,DevExpress.XtraEditors.ProgressBarControl progress)
        {
            try
            {
                sizeRequest = (HttpWebRequest)WebRequest.Create(url);
                int size = (int)sizeRequest.GetResponse().ContentLength;
                progress.Invoke(
                    (MethodInvoker)(() => progress.Properties.Maximum = size));             
              httpRequest = (HttpWebRequest)
WebRequest.Create(url);
                httpRequest.Method = WebRequestMethods.Http.Get;
                HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();
                ftpStream = httpResponse.GetResponseStream();
                fs = File.Create(save_to);               
                byte[] buffer = new byte[10240];
                int read;
                while (fs!=null && (read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
                {                       
                        fs.Write(buffer, 0, read);
                        int position = (int)fs.Position;
                        progress.Invoke(
                            (MethodInvoker)(() => progress.Position = position));  
                }                
            }
            catch (Exception e)
            {
                if (e.Message.Contains("Запрос отменен"))
                    return;
                throw new Exception(e.Message);
            }
            StopDownload();
        }
    }
READ ALSO
c# [DllImport] в методе, функция из dll без обьявления

c# [DllImport] в методе, функция из dll без обьявления

Можно ли как-то в c# в самом методе подключить функцию из dll ? То есть, подобную конструкцию засунуть в метод (например метод Main):

189
GridContol Devexpress WPF MVVM [требует правки]

GridContol Devexpress WPF MVVM [требует правки]

I have many data from observable collection, the data in back end loaded asynchronousThe pattern is MVVM WPF

230
Лямбда-выражение

Лямбда-выражение

Рихтер пишет, что такое выражение:

191
__line__ номер линии кода

__line__ номер линии кода

Не первый раз приходится писать

173