Click here to Skip to main content
15,394,479 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
I am developing a Download Manager. It works fine for one single file but, for multiple files it is not working properly: what is wrong?

When I enter first url, it works fine, but when I click on pause and try a second url after clicking on download, the first file's progress bar starts from 0, and the first file starts downloading automatically without clicking on resume.

When I click on pause, both files pause, when I click on resume both files start downloading. Why this is happening? When I click pause on first url downloading window, I want only the first file to pause, and when I click on resume, only that file should be resumed.

ViewModel:

C#
namespace DownloadManager
{
    public class ViewModel : INotifyPropertyChanged
    {
        public ICommand _Download { get; set; }
        public ICommand Pause { get; set; }

        public ICommand Resume { get; set; }
        public ViewModel()
        {
            _Download = new Command(Start, canExecuteMethod);
            Pause = new Command(Pause_Download, canExecuteMethod);
            Resume = new Command(Resume_Download, canExecuteMethod);
        }
        private bool canExecuteMethod(object parameter)
        {
            return true;
        }
        private void Start(object parameter) //Download Method
        {
            new Add_URL().Button_Click_1(link);
        }
        private void Pause_Download(object parameter) //Pause Download
        {
            new Add_URL().Pause();
        }
        private void Resume_Download(object parameter) //Resume Download
        { 
            new Add_URL().Resume();
        }
        
        public event PropertyChangedEventHandler? PropertyChanged;
        
        private string link;
        public string Link
        {
            get { return link; }
            set { link = value; OnPropertyChanged(Link); }
        }
        
        private void OnPropertyChanged(string property)
        {
            if(PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
    }
}



Model:

C#
<pre>public static bool CheckForInternetConnection()
{
    try
    {
        using (var client = new WebClient())
        using (var stream = client.OpenRead("http://www.google.com"))
        {
            return true;
        }
    }
    catch
    {
        return false;
    }
}

 Download fw;
static int row = 0;

public void Button_Click_1(string link)
{
    Uri uri = null;
    if (CheckForInternetConnection())
    {
        {
            uri = new Uri(link);
            if (!uri.IsFile)
            {
                WarningUrl.Content = "File Found";
                file = true;
            }
        }
    }
    else
    {
        WarningUrl.Content = "No Internet";
    }
    if (file)
    {
        String name = link;
        Add_URL a = new Add_URL();
        String FileName = System.IO.Path.GetFileName(uri.AbsolutePath);
        MainWindow mainwindow = new MainWindow();
        string check = mainwindow.Check(FileName);
               
        MainWindow m = Application.Current.MainWindow as MainWindow;
        //Extension
        string extension = System.IO.Path.GetExtension(FileName);
        var s = GetFileSize(uri);
        int x = Int32.Parse(s); //size in KB
        var fileSizeInMegaByte = Math.Round(Convert.ToDouble(s) / 1024.0 / 1024.0, 2).ToString();
        String size = fileSizeInMegaByte + " MB";  // For addgin in list (MB)

        String time = DateTime.Now.ToString("g");
        Download download = new Download();
        // var method2 = new Action(() => { download.pb.Value = 90; });
        var method2 = new Action<int>(i =>
        {
            download.pb.Value = i;

            MainWindow m = Application.Current.MainWindow as MainWindow;
            if (i< 100)
            {
                m.change(download, i.ToString(), row, FileName);
            }

            download.FileName1.Content = FileName;
        });
        
        var method3 = new Action(() =>
        {
            download.pb.Value = 100;
            string a = "100";
            m.change(download, a, row, FileName);
            row++;
            download.Status.Content = "Completed";
            download.Close();
        });

        fw = new Download(name, path + @"\" + FileName, x);

        CancellationTokenSource tokenSource = new CancellationTokenSource();
        CancellationToken token = tokenSource.Token;
        mre.Set();
        new Thread(() =>
        {
            while (!fw.Done)
            {
                mre.WaitOne();

                double receive = double.Parse(fw.BytesWritten.ToString());

                double Filesize = x;
                double Percentage = receive / Filesize * 100;
                int per = int.Parse(Math.Truncate(Percentage).ToString());

                try
                {
                    Thread.Sleep(300);
                    this.Dispatcher.Invoke(() =>
                    {
                        method2(per);
                        if (fw.Done)
                        {
                            method3();
                        }
                    });
                }
                catch (Exception ex) 
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }).Start();
        fw.Start();       ---> throws exception here
        download.Show();
        m.AddItem(a, FileName, extension, time, size);
        Close();
    }            
}

public void Pause()
{
    fw.Pause1();
}

public void Resume() 
{
    fw.Start();
}


What I have tried:

Check out this image :-- https://i.stack.imgur.com/e6hZB.png[^]



I have tried above things but didn't work properly.

What can I do?

Please help!!
Posted
Updated 4-Feb-22 3:35am
v2
Comments
Richard Deeming 4-Feb-22 9:13am
   
As I said on your StackOverflow question[^]:

At a guess, your fw and row fields should not be static. At the moment, there will only ever be a single instance of those fields across your process lifetime, so pausing that one instance will pause everything that depends on it.

Beyond that, the repeated new Add_URL() calls suggest you haven't understood how object instances work. I suspect you want a single Add_URL instance per ViewModel instance.

(And before you reply with the same comment: "Not working properly" is not enough information for anyone to help you. Provide a clear and precise description of what you have tried and where you are stuck.)
Nehal Chaudhari 4-Feb-22 9:15am
   
Thank you sir, If I remove static from fw the pause and remove functions are not working.
Richard Deeming 4-Feb-22 9:18am
   
Once again: "not working" tells us precisely nothing.

Show us what you have tried, and explain precisely where you are stuck.
Nehal Chaudhari 4-Feb-22 9:30am
   
Yes sir, I meant to say it throws exception while calling method fw.start()
"object reference not set to an instance". thats' why I declared it as static.
Richard Deeming 4-Feb-22 9:32am
   
Which means you've not initialized the field.

We still can't see your updated code, so we have no idea what you have tried.
Nehal Chaudhari 4-Feb-22 9:36am
   
Now I have updated the code marked with ----->

it is throwing exception over there.
Richard Deeming 4-Feb-22 9:48am
   
And we STILL come back to the fact that you don't understand how objects work.

You keep creating new instances of the Add_URL class, calling methods on them, and then throwing them away. And you're then surprised when the new instance of the class doesn't have the same state as the previous instance of the class.

Imagine Add_URL is a car. You get into a new car and put your phone in the glovebox. You then get out and walk away. Some time later, you get into a different car; would you expect your phone to be in the glovebox of that car?
Nehal Chaudhari 4-Feb-22 10:58am
   
Ok sir, I will work on it. Thank You

1 solution

[reposted as original solution could not be edited]

Your code is very unclean. It looks like you're attempting to use MVVM but IMHO you are far from adhering to the principles.

Thread programming is not simple even when you know what you are doing. Why are you not using Asyncronous programming?

Also, be aware that you're limited with the number of threads that you can allocate based on the number of cores in your CPU. This can be overridden but you need to know what you are doing and the ramifications of doing so.

UPDATE: Here are a couple of examples on GitHub with C# source code that you may want to check out to help you:
* OctaneDownloader
* Downloader
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900