Free cookie consent management tool by TermsFeed Policy Generator

Ticket #2965: CancelableSaveFile.patch

File CancelableSaveFile.patch, 20.6 KB (added by pfleck, 6 years ago)
  • HeuristicLab.Common/3.3/Content/ContentManager.cs

     
    2020#endregion
    2121
    2222using System;
     23using System.Threading;
    2324
    2425namespace HeuristicLab.Common {
    2526  public abstract class ContentManager {
     
    4243    public static void LoadAsync(string filename, Action<IStorableContent, Exception> loadingCompletedCallback) {
    4344      if (instance == null) throw new InvalidOperationException("ContentManager is not initialized.");
    4445      var func = new Func<string, IStorableContent>(instance.LoadContent);
    45       func.BeginInvoke(filename, delegate(IAsyncResult result) {
     46      func.BeginInvoke(filename, delegate (IAsyncResult result) {
    4647        Exception error = null;
    4748        IStorableContent content = null;
    4849        try {
    4950          content = func.EndInvoke(result);
    5051          content.Filename = filename;
    51         }
    52         catch (Exception ex) {
     52        } catch (Exception ex) {
    5353          error = ex;
    5454        }
    5555        loadingCompletedCallback(content, error);
     
    5757    }
    5858    protected abstract IStorableContent LoadContent(string filename);
    5959
    60     public static void Save(IStorableContent content, string filename, bool compressed) {
     60    public static void Save(IStorableContent content, string filename, bool compressed, CancellationToken cancellationToken = default(CancellationToken)) {
    6161      if (instance == null) throw new InvalidOperationException("ContentManager is not initialized.");
    62       instance.SaveContent(content, filename, compressed);
     62      instance.SaveContent(content, filename, compressed, cancellationToken);
    6363      content.Filename = filename;
    6464    }
    65     public static void SaveAsync(IStorableContent content, string filename, bool compressed, Action<IStorableContent, Exception> savingCompletedCallback) {
     65    public static void SaveAsync(IStorableContent content, string filename, bool compressed, Action<IStorableContent, Exception> savingCompletedCallback, CancellationToken cancellationToken = default(CancellationToken)) {
    6666      if (instance == null) throw new InvalidOperationException("ContentManager is not initialized.");
    67       var action = new Action<IStorableContent, string, bool>(instance.SaveContent);
    68       action.BeginInvoke(content, filename, compressed, delegate(IAsyncResult result) {
     67      var action = new Action<IStorableContent, string, bool, CancellationToken>(instance.SaveContent);
     68      action.BeginInvoke(content, filename, compressed, cancellationToken, delegate (IAsyncResult result) {
    6969        Exception error = null;
    7070        try {
    7171          action.EndInvoke(result);
    7272          content.Filename = filename;
    73         }
    74         catch (Exception ex) {
     73        } catch (Exception ex) {
    7574          error = ex;
    7675        }
    7776        savingCompletedCallback(content, error);
     
    7877      }, null);
    7978
    8079    }
    81     protected abstract void SaveContent(IStorableContent content, string filename, bool compressed);
     80    protected abstract void SaveContent(IStorableContent content, string filename, bool compressed, CancellationToken cancellationToken);
    8281  }
    8382}
  • HeuristicLab.Core/3.3/PersistenceContentManager.cs

     
    2020#endregion
    2121
    2222using System.IO.Compression;
     23using System.Threading;
    2324using HeuristicLab.Common;
    2425using HeuristicLab.Persistence.Default.Xml;
    2526
     
    3132      return XmlParser.Deserialize<IStorableContent>(filename);
    3233    }
    3334
    34     protected override void SaveContent(IStorableContent content, string filename, bool compressed) {
    35       XmlGenerator.Serialize(content, filename, compressed ? CompressionLevel.Optimal : CompressionLevel.NoCompression);
     35    protected override void SaveContent(IStorableContent content, string filename, bool compressed, CancellationToken cancellationToken) {
     36      XmlGenerator.Serialize(content, filename, compressed ? CompressionLevel.Optimal : CompressionLevel.NoCompression, cancellationToken);
    3637    }
    3738  }
    3839}
  • HeuristicLab.Optimizer/3.3/FileManager.cs

     
    2222using System;
    2323using System.Collections.Generic;
    2424using System.IO;
     25using System.Threading;
    2526using System.Windows.Forms;
    2627using HeuristicLab.Common;
    2728using HeuristicLab.Core;
     
    7778        IView view = MainFormManager.MainForm.ShowContent(content);
    7879        if (view == null)
    7980          ErrorHandling.ShowErrorDialog("There is no view for the loaded item. It cannot be displayed.", new InvalidOperationException("No View Available"));
    80       }
    81       catch (Exception ex) {
     81      } catch (Exception ex) {
    8282        ErrorHandling.ShowErrorDialog((Control)MainFormManager.MainForm, "Cannot open file.", ex);
    83       }
    84       finally {
     83      } finally {
    8584        ((MainForm.WindowsForms.MainForm)MainFormManager.MainForm).ResetAppStartingCursor();
    8685      }
    8786    }
     
    9998          SaveAs(view);
    10099        else {
    101100          MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().SetAppStartingCursor();
    102           SetSaveOperationProgressInContentViews(content, true);
    103           ContentManager.SaveAsync(content, content.Filename, true, SavingCompleted);
     101          var cancellationTokenSource = new CancellationTokenSource();
     102          AddProgressInContentViews(content, cancellationTokenSource);
     103          ContentManager.SaveAsync(content, content.Filename, true, SavingCompleted, cancellationTokenSource.Token);
    104104        }
    105105      }
    106106    }
     
    131131
    132132        if (saveFileDialog.ShowDialog() == DialogResult.OK) {
    133133          MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().SetAppStartingCursor();
    134           SetSaveOperationProgressInContentViews(content, true, saveFileDialog.FileName);
    135           if (saveFileDialog.FilterIndex == 1) {
    136             ContentManager.SaveAsync(content, saveFileDialog.FileName, false, SavingCompleted);
    137           } else {
    138             ContentManager.SaveAsync(content, saveFileDialog.FileName, true, SavingCompleted);
    139           }
     134          bool compressed = saveFileDialog.FilterIndex != 1;
     135          var cancellationTokenSource = new CancellationTokenSource();
     136          AddProgressInContentViews(content, cancellationTokenSource, saveFileDialog.FileName);
     137
     138          ContentManager.SaveAsync(content, saveFileDialog.FileName, compressed, SavingCompleted, cancellationTokenSource.Token);
    140139        }
    141140      }
    142141    }
     
    144143      try {
    145144        if (error != null) throw error;
    146145        MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().UpdateTitle();
    147       }
    148       catch (Exception ex) {
     146      } catch (OperationCanceledException) {
     147      } catch (Exception ex) {
    149148        ErrorHandling.ShowErrorDialog((Control)MainFormManager.MainForm, "Cannot save file.", ex);
    150       }
    151       finally {
    152         SetSaveOperationProgressInContentViews(content, false);
     149      } finally {
     150        Progress.Hide(content);
    153151        MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().ResetAppStartingCursor();
    154152      }
    155153    }
    156154
    157     private static void SetSaveOperationProgressInContentViews(IStorableContent content, bool showProgress, string fileName = null) {
    158       HeuristicLab.MainForm.WindowsForms.MainForm mainForm = MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>();
    159       #region Mono Compatibility
    160       // removed the InvokeRequired check because of Mono
    161       mainForm.Invoke((Action)delegate {
    162         if (showProgress) {
    163           Progress.ShowMarquee(content, string.Format("Saving to file \"{0}\"...", Path.GetFileName(fileName ?? content.Filename)));
    164         } else
    165           Progress.Hide(content);
    166       });
    167       #endregion
     155    private static void AddProgressInContentViews(IStorableContent content, CancellationTokenSource cancellationTokenSource, string fileName = null) {
     156      string message = string.Format("Saving to file \"{0}\"...", Path.GetFileName(fileName ?? content.Filename));
     157      Progress.Show(content, message, ProgressMode.Indeterminate, cancelRequestHandler: () => cancellationTokenSource.Cancel());
    168158    }
    169159  }
    170160}
  • HeuristicLab.Persistence/3.3/Default/Xml/XmlGenerator.cs

     
    2525using System.IO.Compression;
    2626using System.Linq;
    2727using System.Text;
     28using System.Threading;
    2829using HeuristicLab.Persistence.Core;
    2930using HeuristicLab.Persistence.Core.Tokens;
    3031using HeuristicLab.Persistence.Interfaces;
     
    6061      Depth = 0;
    6162    }
    6263
    63     protected enum NodeType { Start, End, Inline } ;
     64    protected enum NodeType { Start, End, Inline };
    6465
    6566    protected static void AddXmlTagContent(StringBuilder sb, string name, Dictionary<string, string> attributes) {
    6667      sb.Append(name);
     
    255256          {"id", lastTypeToken.Id.ToString()},
    256257          {"typeName", lastTypeToken.TypeName },
    257258          {"serializer", lastTypeToken.Serializer }});
    258       }
    259       finally {
     259      } finally {
    260260        lastTypeToken = null;
    261261      }
    262262    }
     
    283283    /// </summary>
    284284    /// <param name="o">The object.</param>
    285285    /// <param name="filename">The filename.</param>
    286     public static void Serialize(object o, string filename) {
    287       Serialize(o, filename, ConfigurationService.Instance.GetConfiguration(new XmlFormat()), false, CompressionLevel.Optimal);
     286    public static void Serialize(object o, string filename, CancellationToken cancellationToken = default(CancellationToken)) {
     287      Serialize(o, filename, ConfigurationService.Instance.GetConfiguration(new XmlFormat()), false, CompressionLevel.Optimal, cancellationToken);
    288288    }
    289289
    290290    /// <summary>
     
    295295    /// <param name="o">The object.</param>
    296296    /// <param name="filename">The filename.</param>
    297297    /// <param name="compression">ZIP file compression level</param>
    298     public static void Serialize(object o, string filename, CompressionLevel compression) {
    299       Serialize(o, filename, ConfigurationService.Instance.GetConfiguration(new XmlFormat()), false, compression);
     298    public static void Serialize(object o, string filename, CompressionLevel compression, CancellationToken cancellationToken = default(CancellationToken)) {
     299      Serialize(o, filename, ConfigurationService.Instance.GetConfiguration(new XmlFormat()), false, compression, cancellationToken);
    300300    }
    301301
    302302    /// <summary>
     
    306306    /// <param name="obj">The object.</param>
    307307    /// <param name="filename">The filename.</param>
    308308    /// <param name="config">The configuration.</param>
    309     public static void Serialize(object obj, string filename, Configuration config) {
    310       Serialize(obj, filename, config, false, CompressionLevel.Optimal);
     309    public static void Serialize(object obj, string filename, Configuration config, CancellationToken cancellationToken = default(CancellationToken)) {
     310      Serialize(obj, filename, config, false, CompressionLevel.Optimal, cancellationToken);
    311311    }
    312312
    313     private static void Serialize(object obj, Stream stream, Configuration config, bool includeAssemblies
    314    , CompressionLevel compression) {
     313    private static void Serialize(object obj, Stream stream, Configuration config, bool includeAssemblies, CompressionLevel compression, CancellationToken cancellationToken = default(CancellationToken)) {
    315314      Serializer serializer = new Serializer(obj, config);
    316       Serialize(stream, includeAssemblies, compression, serializer);
     315      Serialize(stream, includeAssemblies, compression, serializer, cancellationToken);
    317316    }
    318317
    319     private static void Serialize(Stream stream, bool includeAssemblies, CompressionLevel compression, Serializer serializer) {
     318    private static void Serialize(Stream stream, bool includeAssemblies, CompressionLevel compression, Serializer serializer, CancellationToken cancellationToken = default(CancellationToken)) {
    320319      try {
     320        cancellationToken.ThrowIfCancellationRequested();
    321321        DateTime start = DateTime.Now;
    322322        serializer.InterleaveTypeInformation = false;
    323323        XmlGenerator generator = new XmlGenerator();
     
    325325          ZipArchiveEntry entry = zipArchive.CreateEntry("data.xml", compression);
    326326          using (StreamWriter writer = new StreamWriter(entry.Open())) {
    327327            foreach (ISerializationToken token in serializer) {
     328              cancellationToken.ThrowIfCancellationRequested();
    328329              string line = generator.Format(token);
    329330              writer.Write(line);
    330331            }
     
    337338          }
    338339          if (includeAssemblies) {
    339340            foreach (string name in serializer.RequiredFiles) {
     341              cancellationToken.ThrowIfCancellationRequested();
    340342              Uri uri = new Uri(name);
    341343              if (!uri.IsFile) {
    342344                Logger.Warn("cannot read non-local files");
     
    347349                using (FileStream reader = File.OpenRead(uri.PathAndQuery)) {
    348350                  byte[] buffer = new byte[1024 * 1024];
    349351                  while (true) {
     352                    cancellationToken.ThrowIfCancellationRequested();
    350353                    int bytesRead = reader.Read(buffer, 0, 1024 * 1024);
    351354                    if (bytesRead == 0)
    352355                      break;
     
    359362        }
    360363        Logger.Info(String.Format("serialization took {0} seconds with compression level {1}",
    361364          (DateTime.Now - start).TotalSeconds, compression));
    362       }
    363       catch (Exception) {
     365      } catch (Exception) {
    364366        Logger.Warn("Exception caught, no data has been serialized.");
    365367        throw;
    366368      }
     
    374376    /// <param name="config">The configuration.</param>
    375377    /// <param name="includeAssemblies">if set to <c>true</c> include needed assemblies.</param>
    376378    /// <param name="compression">The ZIP compression level.</param>
    377     public static void Serialize(object obj, string filename, Configuration config, bool includeAssemblies, CompressionLevel compression) {
     379    public static void Serialize(object obj, string filename, Configuration config, bool includeAssemblies, CompressionLevel compression, CancellationToken cancellationToken = default(CancellationToken)) {
     380      string tempfile = null;
    378381      try {
    379         string tempfile = Path.GetTempFileName();
     382        tempfile = Path.GetTempFileName();
    380383
    381384        using (FileStream stream = File.Create(tempfile)) {
    382           Serialize(obj, stream, config, includeAssemblies, compression);
     385          Serialize(obj, stream, config, includeAssemblies, compression, cancellationToken);
    383386        }
    384 
     387        // copy only if needed
    385388        File.Copy(tempfile, filename, true);
    386         File.Delete(tempfile);
    387       }
    388       catch (Exception) {
     389      } catch (Exception) {
    389390        Logger.Warn("Exception caught, no data has been written.");
    390391        throw;
     392      } finally {
     393        if (tempfile != null && File.Exists(tempfile))
     394          File.Delete(tempfile);
    391395      }
    392396    }
    393397
     
    398402    /// <param name="obj">The object.</param>
    399403    /// <param name="stream">The stream.</param>
    400404    /// <param name="compressionType">Type of compression, default is GZip.</param>
    401     public static void Serialize(object obj, Stream stream, CompressionType compressionType = CompressionType.GZip) {
    402       Serialize(obj, stream, ConfigurationService.Instance.GetConfiguration(new XmlFormat()), compressionType);
     405    public static void Serialize(object obj, Stream stream, CompressionType compressionType = CompressionType.GZip, CancellationToken cancellationToken = default(CancellationToken)) {
     406      Serialize(obj, stream, ConfigurationService.Instance.GetConfiguration(new XmlFormat()), compressionType, cancellationToken);
    403407    }
    404408
    405409
     
    410414    /// <param name="stream">The stream.</param>
    411415    /// <param name="config">The configuration.</param>
    412416    /// <param name="compressionType">Type of compression, default is GZip.</param>
    413     public static void Serialize(object obj, Stream stream, Configuration config, CompressionType compressionType = CompressionType.GZip) {
    414       Serialize(obj, stream, config, false, compressionType);
     417    public static void Serialize(object obj, Stream stream, Configuration config, CompressionType compressionType = CompressionType.GZip, CancellationToken cancellationToken = default(CancellationToken)) {
     418      Serialize(obj, stream, config, false, compressionType, cancellationToken);
    415419    }
    416420
    417421    /// <summary>
     
    422426    /// <param name="config">The configuration.</param>
    423427    /// <param name="includeAssemblies">if set to <c>true</c> include need assemblies.</param>
    424428    /// <param name="compressionType">Type of compression, default is GZip.</param>
    425     public static void Serialize(object obj, Stream stream, Configuration config, bool includeAssemblies,
    426                                  CompressionType compressionType = CompressionType.GZip) {
     429    public static void Serialize(object obj, Stream stream, Configuration config, bool includeAssemblies, CompressionType compressionType = CompressionType.GZip, CancellationToken cancellationToken = default(CancellationToken)) {
    427430      try {
    428431        Serializer serializer = new Serializer(obj, config);
    429432        if (compressionType == CompressionType.Zip) {
    430           Serialize(obj, stream, config, includeAssemblies, CompressionLevel.Optimal);
     433          Serialize(obj, stream, config, includeAssemblies, CompressionLevel.Optimal, cancellationToken);
    431434        } else {
    432           Serialize(stream, serializer);
     435          Serialize(stream, serializer, cancellationToken);
    433436        }
    434       }
    435       catch (PersistenceException) {
     437      } catch (PersistenceException) {
    436438        throw;
    437       }
    438       catch (Exception e) {
     439      } catch (Exception e) {
    439440        throw new PersistenceException("Unexpected exception during Serialization.", e);
    440441      }
    441442    }
     
    450451    /// <param name="types">The list of all serialized types.</param>
    451452    /// <param name="compressionType">Type of compression, default is GZip.</param>
    452453    public static void Serialize(object obj, Stream stream, Configuration config, bool includeAssemblies, out IEnumerable<Type> types,
    453                                  CompressionType compressionType = CompressionType.GZip) {
     454                                 CompressionType compressionType = CompressionType.GZip, CancellationToken cancellationToken = default(CancellationToken)) {
    454455      try {
    455456        Serializer serializer = new Serializer(obj, config);
    456457        if (compressionType == CompressionType.Zip) {
    457           Serialize(stream, includeAssemblies, CompressionLevel.Optimal, serializer);
     458          Serialize(stream, includeAssemblies, CompressionLevel.Optimal, serializer, cancellationToken);
    458459        } else {
    459           Serialize(stream, serializer);
     460          Serialize(stream, serializer, cancellationToken);
    460461        }
    461462        types = serializer.SerializedTypes;
    462       }
    463       catch (PersistenceException) {
     463      } catch (PersistenceException) {
    464464        throw;
    465       }
    466       catch (Exception e) {
     465      } catch (Exception e) {
    467466        throw new PersistenceException("Unexpected exception during Serialization.", e);
    468467      }
    469468    }
    470469
    471     private static void Serialize(Stream stream, Serializer serializer) {
     470    private static void Serialize(Stream stream, Serializer serializer, CancellationToken cancellationToken = default(CancellationToken)) {
     471      cancellationToken.ThrowIfCancellationRequested();
    472472      using (StreamWriter writer = new StreamWriter(new GZipStream(stream, CompressionMode.Compress))) {
    473473        serializer.InterleaveTypeInformation = true;
    474474        XmlGenerator generator = new XmlGenerator();
    475475        foreach (ISerializationToken token in serializer) {
     476          cancellationToken.ThrowIfCancellationRequested();
    476477          string line = generator.Format(token);
    477478          writer.Write(line);
    478479        }