DotNetZip 取消任务中的提取

DotNetZip Cancel extraction in Task

我有一个在任务中执行 zip 解压缩的方法。现在我想要取消操作的能力。但是当我调用 Cancel() 方法时,一切似乎都立即停止并且 while 永远运行:

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);
        }
    }
}

我已经在 args.Cancel = _cancelExtraction; 上设置了一个断点,但是一旦 Cancel() 方法被调用,事件就不再触发了。

我找到了解决方法。我基本上摆脱了我自己的 Cancel 方法,并按照 dotnetzip 框架的要求进行操作。在进度事件中。

假设您想在 Form 关闭时取消操作。我捕获 FormClosing 事件,取消关闭过程并记住关闭请求。下次进度事件触发时,我在事件参数中设置 cancel 属性 并在 completed 事件中自己关闭 Form 事件:

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;
    }
}

我觉得它很丑,但它确实有效....