现在有一个用C#写的windows service,每一分钟执行一次,其中有一个写log日志的方法:
        String path;
        FileStream log;
        StreamWriter writer;        public void writeLog(LogLevel outLevel, String[] data)
        {
            lock (lockobj)
            {                if (level <= (int)outLevel)
                {
                    try
                    {
                        String rotatePath;
                        if (path.Contains("_D_A_T_E_"))
                        {
                            rotatePath = path.Replace("_D_A_T_E_", "_" + DateTime.Now.ToString("yyyyMMdd"));
                        }
                        else if (path.Contains("_M_O_N_T_H_"))
                        {
                            rotatePath = path.Replace("_M_O_N_T_H_", "_" + DateTime.Now.ToString("yyyyMM"));
                        }
                        else
                        {
                            rotatePath = path;
                        }
                        log = new FileStream(rotatePath, FileMode.Append, FileAccess.Write, FileShare.Read);
                        writer = new StreamWriter(log);                        writer.Write(
                            "[" + System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "] " +
                            "[" + outLevel + "] ");                        writer.Write("[");                        StringBuilder sb = new StringBuilder();
                        foreach (String str in data)
                        {
                            sb.Append(str + ",");
                        }
                        writer.Write(sb.ToString().TrimEnd(','));
                        writer.Write("]\n");
                        writer.Flush();
                        writer.Close();
                        writer.Dispose();
                    }
                    catch
                    {
                    }
                }
            }
        } 现在的问题是:writer = new StreamWriter(log);
writer 对象生成后,资源释放不了,用perfmon监视查看,内存消耗差不多每一分钟都有增长。
其他所有的都注释掉了,单单运行log输出这一块。
GC.SuppressFinalize(this);
using(writer = new StreamWriter(log)){ }
都试过,还是不行
想问一下如何能彻底释放掉write的资源,谢谢

解决方案 »

  1.   

    1、用log4net写日志。2、log = new FileStream(rotatePath, FileMode.Append, FileAccess.Write, FileShare.Read); log没释放
      writer = new StreamWriter(log);
    改为
    using(log = new FileStream(rotatePath, FileMode.Append, FileAccess.Write, FileShare.Read);)
    {
            ...
         log.close();
    }
      

  2.   


       String path;
      FileStream log;
      StreamWriter writer;
    宣告到方法裹头
    应该是会释放掉的~
      

  3.   


    不只log没释放的原因,曾经这样写过:
                            using (log = new FileStream(rotatePath, FileMode.Append, FileAccess.Write, FileShare.Read))
                            {
                                using (writer = new StreamWriter(log))
                                {
                                    writer.Write(
                                        "[" + System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "] " +
                                        "[" + outLevel + "] ");                                writer.Write("[");                                StringBuilder sb = new StringBuilder();
                                    foreach (String str in data)
                                    {
                                        sb.Append(str + ",");
                                    }
                                    writer.Write(sb.ToString().TrimEnd(','));
                                    writer.Write("]\n");
                                    writer.Flush();
                                    writer.Close();
                                    writer.Dispose();
                                    log.Flush();
                                    log.Close();
                                    log.Dispose();
                                }
                            }
    还是没用的。
    把有关write的内容注释掉,只留有log部分,内存变量不变。
    所以感觉和log部分无关。
      

  4.   

    不要把文件流之类的定义为成员变量,因为这些流,一般需要用完后立即释放
    把你中间的代码改了下            try
                {
                    using (FileStream log = new FileStream(rotatePath, FileMode.Append, FileAccess.Write, FileShare.Read))
                    {
                        using (StreamWriter writer = new StreamWriter(log))
                        {
                            writer.Write(
                            "[" + System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "] " +
                            "[" + outLevel + "] ");                        writer.Write("[");                        StringBuilder sb = new StringBuilder();
                            foreach (String str in data)
                            {
                                sb.Append(str + ",");
                            }
                            writer.Write(sb.ToString().TrimEnd(','));
                            writer.Write("]\n");
                            writer.Flush();
                            writer.Close();
                            writer.Dispose();
                        }
                        log.Close();
                        log.Dispose();
                    }
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
      

  5.   

      FileStream log;
      StreamWriter writer;
    写到函数头试试看还有
      writer.Close();
      writer.Dispose();写到finally里面比较好
    if (writer != null) {
    writer.Close();
    writer.Dispose();
    }我个人觉得这些法没有问题
    lock (lockobj),但是前提是lockobj是个静态变量,或者该log操作类只有唯一一个实例
      

  6.   

    那你用玩之后把 
    log.close();
    log = null;
    writer .close();
    writer = null;
    这个样子呢
      

  7.   

    通过上面的了解,感觉不像是这个函数的问题,你这样试试:public void writeLog(LogLevel outLevel, String[] data)屏蔽这个函数里面所有执行代码!看看还有这种现象没?个人觉得是外部的参数String[] data造成!
      

  8.   

            public void writeLog(LogLevel outLevel, String[] data)
            {
                FileStream log;
                StreamWriter writer;            lock (lockobj)
                {                if (level <= (int)outLevel)
                    {
                        try
                        {
                            String rotatePath;
                            if (path.Contains("_D_A_T_E_"))
                            {
                                rotatePath = path.Replace("_D_A_T_E_", "_" + DateTime.Now.ToString("yyyyMMdd"));
                            }
                            else if (path.Contains("_M_O_N_T_H_"))
                            {
                                rotatePath = path.Replace("_M_O_N_T_H_", "_" + DateTime.Now.ToString("yyyyMM"));
                            }
                            else
                            {
                                rotatePath = path;
                            }
                            log = new FileStream(rotatePath, FileMode.Append, FileAccess.Write, FileShare.Read);
                            //writer = new StreamWriter(log);                        //writer.Write(
                            //    "[" + System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "] " +
                            //    "[" + outLevel + "] ");                        //writer.Write("[");                        //StringBuilder sb = new StringBuilder();
                            //foreach (String str in data)
                            //{
                            //    sb.Append(str + ",");
                            //}
                            //writer.Write(sb.ToString().TrimEnd(','));
                            //writer.Write("]\n");
                            //writer.Flush();
                            //writer.Close();                    }
                        catch
                        {
                        }
                    }
                }
            }
    如果把write的部分注释掉,运行的话,内存是不增加的
      

  9.   

    把这两家代码:
      log = new FileStream(rotatePath, FileMode.Append, FileAccess.Write, FileShare.Read);
      writer = new StreamWriter(log);放到类的构造函数!
      

  10.   

    我建议使用的时候只用  Using()
                                {
                                 }
      

  11.   

    LZ 我看你 log实例化之后 后面的代码都没将log干掉。会不会是这个原因。
      

  12.   


    试了,不是正解,放到构造函数后,只第一次能出力log,后面的就都不能出力了
      

  13.   


    不是,我也曾认为是这个原因,加了   log.Flush();
       log.Close();
       log.Dispose();
    但没有效果,不是这个原因
      

  14.   

    如果楼主以上方式都试过
    那就不知道什么原因了,这种情况没遇到过。
    把写日志的方法写成一个类 
    然后
      String path;
      FileStream log;
      StreamWriter writer;
      没必要是全局的。
      如果在不行(就log4net),实在不想用就请高手请教,我也学习下。