在后台工作程序中序列化数据 - 内存不足异常

时间:2015-10-14 11:38:06

标签: c# out-of-memory backgroundworker

我使用binaryformatter序列化一个类并使用deflatestream压缩数据。保存功能如下,并从后台工作人员调用:

public static void save(System system, String filePath) 
{
    //Make filestream
    FileStream fs = new FileStream(filePath, FileMode.Create);
    try 
    {
        //Serialize offerte
        BinaryFormatter bf = new BinaryFormatter();
        DeflateStream cs = new DeflateStream(fs, CompressionMode.Compress);

        bf.Serialize(cs, system);

        //Push through
        fs.Flush();
        cs.Flush();
        cs.Close();
    } 
    catch (Exception e) 
    {
        var mess = e.Message;
    } 
    finally 
    {
        //Close
        fs.Close();
    }
}

该课程有许多用户'。有100个用户需要10秒,文件是2MB。有1000个用户,它会给出一个内存不足的异常(估计大小为16MB)。任何人都可以在这里看到问题,或提出如何解决这个问题的建议? (我首先想到后台线程上的时间导致这种情况,需要很长时间。但是我有其他后台线程可以运行更长时间。)

2 个答案:

答案 0 :(得分:4)

你不会处理你的溪流,这可能是问题的一部分,建议:

public static void save(System system, String filePath) 
{
    //Make filestream
    using(FileStream fs = new FileStream(filePath, FileMode.Create))    
    {
        //Serialize offerte
        BinaryFormatter bf = new BinaryFormatter();

        using (DeflateStream cs = new DeflateStream(fs, CompressionMode.Compress)) {

           bf.Serialize(cs, system);

           //Push through
           fs.Flush();
           cs.Flush();
           cs.Close();
       }
    }     
}

这也可以消除您的吞咽异常,这可能是一件好事。

答案 1 :(得分:1)

您使用了几个实现System.IDisposable

的类对象
  

如果设计师实施了IDisposable,他会告诉您他可能会使用稀缺资源。在垃圾收集器收集垃圾之前,您可能会耗尽资源。

换句话说:无论何时使用实现System.IDisposable的类,只要您不再需要该类,就应该调用Dispose()。如果您需要其他类的资源,则尤其需要这样做。

您使用两个Stream类:FileStream和DeflateStream。他们都实现了IDisposable。如果你不调用Dispose(),垃圾收集器最终会,但同时,这些Streams使用的资源对其他任何人都无法使用。

确保处置Disposable对象的最简单方法是使用using语句:

using (var myStream = new FileStream(...))
{
    ... // use myStream
}

当到达右括号时,调用myStream.Dispose(),有效释放它使用的所有稀缺资源。

  

这适用于用于离开{...}块的每个方法,包括break,return和甚至Exceptions。

因此,使用是一种非常安全的方法:始终会调用Dispose()。

顺便说一句:Dispose()也会注意Streams被刷新和关闭,因此在using语句结束时你不必刷新()和关闭()。