I have a method that executes a zip-extraction in a Task. 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:
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;
but the event is not fired anymore as soon as the Cancel()
method is called.
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. In the progress event.
Let's say you want to cancel the operation when the Form
gets closed. I capture the FormClosing
Event, cancel the close procedure and remember the close request. 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:
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....