DotNetZip Undo checkout in Task

I have a method that does a zip extract on a Task. Now I want to be able to undo the operation. But when I call the method Cancel()

, everything seems to stop immediately, but while

is executed forever:

public class OsiSourceZip
{
    private const string ZipPassword = "******";

    private bool _extractionDone;
    private bool _cancelExtraction;

    public async Task Extract(string sourceFile, string extractionDir)
    {
        Task extraction = Task.Run(() =>
        {
            using (ZipFile zipf = ZipFile.Read(sourceFile))
            {
                zipf.ExtractProgress += delegate(object sender, ExtractProgressEventArgs args)
                {
                    args.Cancel = _cancelExtraction;
                    RaiseExtractionProgressUpdate(args);
                };
                zipf.Password = ZipPassword;
                zipf.Encryption = EncryptionAlgorithm.WinZipAes256;
                zipf.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently;
                zipf.ExtractAll(extractionDir);
            }
        });

        await extraction;
        _extractionDone = true;
        RaiseSourceInstallationCompleted();
    }

    public void Cancel()
    {
        _cancelExtraction = true;
        while (!_extractionDone)
        {
            Thread.Sleep(500);
        }
    }
}

      

I set the breakpoint to args.Cancel = _cancelExtraction;

, but the event no longer fires as soon as the method is called Cancel()

.

+3


source to share


1 answer


I found a solution for this. I basically got rid of my own method Cancel

and do it the way dotnetzip Framework wants. In a progress event.

Let's say you want to cancel an operation when it is Form

closed. I capture the event FormClosing

, cancel the close procedure, and remember the close request. Next time the progress event occurs, I set the property Cancel

in the event arguments and close myself Form

to the completed

Event:



public partial class MainForm : Form
{
    private bool _closeRequested;

    private void OnSourceInstallationCompleted(object sender, EventArgs e)
    {
        if (_closeRequested) { this.Close(); }            
    }

    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (!_closeRequested)
        {
            _closeRequested = true;
            e.Cancel = true;
        }
    }

    private void OnExtractionProgressUpdate(object sender, ExtractProgressEventArgs e)
    {
        e.Cancel = _closeRequested;
    }
}

      

I think this is pretty ugly, but it works ...

0


source







All Articles