alanmcgovern / monotorrent

The official repository for MonoTorrent, a bittorrent library for .NET
https://github.com/alanmcgovern/monotorrent
MIT License
1.15k stars 397 forks source link

CancellationToken works chaotically #649

Closed foxi69 closed 3 months ago

foxi69 commented 10 months ago

Is it MonoTorrent error or what?

If "createTorrentsProgressForm" is closed, then "cancellationTokenSource.Cancel();" is called, and after this "Logger.LogToForm(mainForm, "cancelled");" (Work until this)

await torrentCreator.CreateAsync(fileSource, torrentFilePath, cancellationTokenSource.Token); - this should get this token and cancel, but nothing happend.

I am using 2.0.7. Sometimes it works, sometimes it doesn't, same code, nothing changed.

Full code:


public static async Task<bool> CreateTorrentAsync(MainForm mainForm, CreateTorrentsProgressForm createTorrentsProgressForm, string path, string releaseName, int pieceLength = 0, string torrentComment = null, int counter = 0) {
            bool success = false;
            string torrentFilePath = string.Empty;
            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationTokenRegistration cancellationTokenRegistration = new CancellationTokenRegistration();
            try {
                if (Directory.Exists(mainForm.torrentsFolder)) {
                    ITorrentFileSource fileSource = new TorrentFileSource(path, false);
                    torrentFilePath = Path.Combine(mainForm.torrentsFolder, fileSource.TorrentName) + StaticVariables.torrentExtension;
                    if (File.Exists(torrentFilePath)) {
                        File.Delete(torrentFilePath);
                    }
                    TorrentCreator torrentCreator = new TorrentCreator {
                        Private = true,
                        StoreMD5 = true
                    };
                    if (pieceLength > 0) {
                        torrentCreator.PieceLength = pieceLength * 1024;
                    }
                    if (!string.IsNullOrWhiteSpace(torrentComment)) {
                        torrentCreator.Comment = torrentComment;
                    }
                    createTorrentsProgressForm.FormClosing += (sender, e) => {
                        if (e.CloseReason == CloseReason.UserClosing) {
                            cancellationTokenSource.Cancel();
                        }
                    };
                    createTorrentsProgressForm.Show();
                    IProgress<int> progress = new Progress<int>(val => {
                        createTorrentsProgressForm.UpdateProgressBar(val);
                        createTorrentsProgressForm.Refresh();
                        if (val == 100 && counter == 0) {
                            createTorrentsProgressForm.Close();
                        }
                    });
                    cancellationTokenRegistration = cancellationTokenSource.Token.Register(() => {
                        Logger.LogToForm(mainForm, "cancelled");
                    });
                    torrentCreator.Hashed += (o, e) => {
                        int val = Math.Max((int)(e.OverallCompletion * 100), _overall);
                        if (val != _overall) {
                            _overall = val;
                            progress.Report(val);
                        }
                    };
                    createTorrentsProgressForm.UpdateLogTextBox("Creating torrent: " + releaseName + "...");
                    await torrentCreator.CreateAsync(fileSource, torrentFilePath, cancellationTokenSource.Token);
                    success = true;
                }
            }
            catch (Exception ex) {
                Logger.ErrorLogToFile(ex, MethodBase.GetCurrentMethod().Name);
                success = false;
            }
            finally {
                cancellationTokenRegistration.Dispose();
                if (!cancellationTokenSource.Token.IsCancellationRequested && File.Exists(torrentFilePath)) {
                    mainForm.torrentFilesCreated.Add(torrentFilePath);
                }
                if (!createTorrentsProgressForm.IsDisposed && createTorrentsProgressForm != null) {
                    createTorrentsProgressForm.UpdateLogTextBox("Torrent create has been finished: " + releaseName);
                    if (counter == 0 || cancellationTokenSource.Token.IsCancellationRequested) {
                        createTorrentsProgressForm.Close();
                    }
                }
            }
            return success;
        }
alanmcgovern commented 3 months ago

I expect this is working fine in the latest beta release. I took a look at the code in the 2.0 branch and it's vastly different to the 3.0 branch. I'm not going to investigate bugs in that branch at this point - it's easier to upgrade :)

Thanks for reporting, and i hope the 3.0 release works reliably!