Ignore:
Timestamp:
11/23/18 15:37:24 (2 years ago)
Author:
pfleck
Message:

#2965

  • Added CancelationTokens for the Save and Serialize methods.
  • Fixed a potential temp-file-leak when replacing the old file with the new one after serialization.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2965_CancelablePersistence/HeuristicLab.Persistence/3.3/Default/Xml/XmlGenerator.cs

    r15583 r16325  
    2626using System.Linq;
    2727using System.Text;
     28using System.Threading;
    2829using HeuristicLab.Persistence.Core;
    2930using HeuristicLab.Persistence.Core.Tokens;
     
    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) {
     
    256257          {"typeName", lastTypeToken.TypeName },
    257258          {"serializer", lastTypeToken.Serializer }});
    258       }
    259       finally {
     259      } finally {
    260260        lastTypeToken = null;
    261261      }
     
    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
     
    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
     
    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);
    311     }
    312 
    313     private static void Serialize(object obj, Stream stream, Configuration config, bool includeAssemblies
    314    , CompressionLevel compression) {
     309    public static void Serialize(object obj, string filename, Configuration config, CancellationToken cancellationToken = default(CancellationToken)) {
     310      Serialize(obj, filename, config, false, CompressionLevel.Optimal, cancellationToken);
     311    }
     312
     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);
    317     }
    318 
    319     private static void Serialize(Stream stream, bool includeAssemblies, CompressionLevel compression, Serializer serializer) {
     315      Serialize(stream, includeAssemblies, compression, serializer, cancellationToken);
     316    }
     317
     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;
     
    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);
     
    338339          if (includeAssemblies) {
    339340            foreach (string name in serializer.RequiredFiles) {
     341              cancellationToken.ThrowIfCancellationRequested();
    340342              Uri uri = new Uri(name);
    341343              if (!uri.IsFile) {
     
    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)
     
    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;
     
    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);
    383         }
    384 
     385          Serialize(obj, stream, config, includeAssemblies, compression, cancellationToken);
     386        }
     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    }
     
    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
     
    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
     
    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);
    433         }
    434       }
    435       catch (PersistenceException) {
     435          Serialize(stream, serializer, cancellationToken);
     436        }
     437      } catch (PersistenceException) {
    436438        throw;
    437       }
    438       catch (Exception e) {
     439      } catch (Exception e) {
    439440        throw new PersistenceException("Unexpected exception during Serialization.", e);
    440441      }
     
    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);
Note: See TracChangeset for help on using the changeset viewer.