Skip to content
This repository was archived by the owner on Sep 28, 2020. It is now read-only.
This repository was archived by the owner on Sep 28, 2020. It is now read-only.

YoutubeExtractor + Async BackgroundWorker. How to cancel download?.. #173

@Gennady-G

Description

@Gennady-G

Hi guys!

Im. trying to use this lib in WinForm GUI app. Works cool, the only one problem - it cannot stop :-)

BackgroundWorker control allows to set CancellationPending flag, and then manually check it in DoWork function(while processing).

By instance:

    // BackgroundWorker launches Calculate function
    private void MyBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        // not UI thread
        e.Result = Calculate(sender as BackgroundWorker, e);
    }

    // some work in separate thread, where we check CancellationPending flag
    private long Calculate(BackgroundWorker instance, DoWorkEventArgs e)
    {
        for (int i = 0; i < 100; i++)
        {
            if (instance.CancellationPending)
            {
                e.Cancel = true;
                break;
            }
            else
            {
                System.Threading.Thread.Sleep(100);
                instance.ReportProgress(i);
            }
        }
        return 0L;
    }

    // click Cancel button:
   private void buttonCancel_Click(object sender, EventArgs e)
    {
        // set 'CancellationPending' flag to true, calling CancelAsync();
        MyBackgroundWorker.CancelAsync();
        buttonCancel.Enabled = false;
    }

How to realize that with Your library? I was triyng to cancel in DownloadProgressChanged, but app hangs. I think it could be done only in DoWork() function.. Here is big listing what I'm trying to do:

        // show progress in some visual controls..
        private void BackgroundWorker1ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // HANGS, .NET error 
            if (this.backgroundWorker1.CancellationPending)
            {
                this.Logger("Catched CancellationPending!");
                backgroundWorker1.ReportProgress(0);
                return;
            }
        }


        // Background worker job. Code is same as in Your dicumentation(Well, I renamed sender2 and args2)
        // Your Execute is synchronous, but I launch it in Asynchronous backgroundWorker
        private void BackgroundWorker1DoWork(object sender, DoWorkEventArgs e)
        {
            // it should be done during downloadin, BUT How?..
            if (backgroundWorker1.CancellationPending)
            {
                e.Cancel = true;
                return;
            }

            // Our test youtube link
            // todo: get from GUI
            string link = "https://www.youtube.com/watch?v=H7HmzwI67ec";

            // Get the available video formats.
            IEnumerable<VideoInfo> videoInfos = DownloadUrlResolver.GetDownloadUrls(link);

            // todo: try get the best first, then worst
            // Select the first .mp4 video with 360p resolution
            VideoInfo video = videoInfos.First(info => info.VideoType == VideoType.Mp4 && info.Resolution == 360);

            if (video.RequiresDecryption)
            {
                // If the video has a decrypted signature, decipher it
                DownloadUrlResolver.DecryptDownloadUrl(video);
            }

            var videoDownloader = new VideoDownloader(video, Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), RemoveIllegalPathCharacters(video.Title) + video.VideoExtension));

            // Register the ProgressChanged event and print the current progress
            videoDownloader.DownloadProgressChanged += (sender2, args2)
                => backgroundWorker1.ReportProgress((int)args2.ProgressPercentage);

            // Execute the video downloader. For GUI applications note, that this method runs synchronously.
            videoDownloader.Execute();
        }


        // Cancel download by pressing button
        private void buttonCancel_Click(object sender, EventArgs e)
        {
            Logger("Cancel Pressed");

            if (backgroundWorker1.IsBusy)
            {
                // Notify the worker thread that a cancel has been requested.
                // The cancel will not actually happen until the thread in the
                // DoWork checks the m_oWorker.CancellationPending flag. 
                backgroundWorker1.CancelAsync();    
            }
        }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions