简体   繁体   English

DotNetZip取消任务中的提取

[英]DotNetZip Cancel extraction in Task

I have a method that executes a zip-extraction in a Task. 我有一种在Task中执行zip提取的方法。 Now I want the ability to Cancel the operation. 现在,我希望能够取消该操作。 But when I call the Cancel() method everything seems to stop immediately and the while runs forever: 但是当我调用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);
        }
    }
}

I've set a break point on args.Cancel = _cancelExtraction; 我已经在args.Cancel = _cancelExtraction;上设置了一个断点args.Cancel = _cancelExtraction; but the event is not fired anymore as soon as the Cancel() method is called. 但是一旦调用Cancel()方法,就不再触发该事件。

I've found a solution to this. 我已经找到了解决方案。 I basically got rid of my own Cancel Method and do it as the dotnetzip Framework wants it. 我基本上摆脱了我自己的Cancel方法,并按照dotnetzip Framework的要求来执行它。 In the progress event. 在进度事件中。

Let's say you want to cancel the operation when the Form gets closed. 假设您要在Form关闭时取消操作。 I capture the FormClosing Event, cancel the close procedure and remember the close request. 我捕获了FormClosing事件,取消了关闭过程并记住了关闭请求。 The next time the progress event fires, I set the the cancel property in the event args and close the Form myself in the completed Event: 下一次进度事件触发时,我在事件args中设置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;
    }
}

I think it's rather ugly but it works.... 我认为这很丑陋,但是有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM