DotNetZip在任务

时间:2017-04-10 12:20:12

标签: c# task dotnetzip

我有一个在Task中执行zip-extraction的方法。现在我希望能够取消操作。但是,当我调用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()方法,就不会再触发该事件。

1 个答案:

答案 0 :(得分:0)

我找到了解决方法。我基本上摆脱了自己的Cancel方法,并按照dotnetzip Framework的要求进行操作。在进展活动中。

假设您要在Form关闭时取消操作。我捕获FormClosing事件,取消关闭程序并记住关闭请求。触发progress事件的下一次,我在事件args中设置cancel属性并在Form事件中关闭completed我自己:

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

我觉得它相当难看,但它有效......