c#windows服务内存问题(内存泄漏?)

ste*_*cec 2 c# memory memory-leaks timer

我用C#编写的Windows服务中的内存管理有点问题(框架3.5,visual studio 2008).

服务运行正常,有一个Timer和一个CallBack每3分钟触发一次程序.因此,Windows任务管理器中的内存在每个计时器运行时都会缓慢增长.

您是否知道如何解决此问题?

为了简化问题,下面是一个非常简单的代码,可以解决同样的问题:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.IO;

namespace svcTest
{
public partial class svcTest : ServiceBase
{

    private Timer tmr;
    private TimerCallback tmrCallBack;

    public svcTest()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        FileStream fs = new FileStream(@"c:\svclog.txt", FileMode.OpenOrCreate, FileAccess.Write);
        StreamWriter m_streamWriter = new StreamWriter(fs);
        m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
        m_streamWriter.WriteLine("Service Started on " + DateTime.Now.ToLongDateString() + " at " + DateTime.Now.ToLongTimeString());
        m_streamWriter.WriteLine(" *----------------*");
        m_streamWriter.Flush();
        m_streamWriter.Close();

        tmrCallBack = new TimerCallback(goEXE);
        tmr = new Timer(tmrCallBack, null, 0, 1000 * 60 * 1 / 2);
    }

    protected override void OnStop()
    {
        FileStream fs = new FileStream(@"c:\svclog.txt", FileMode.OpenOrCreate, FileAccess.Write);
        StreamWriter m_streamWriter = new StreamWriter(fs);
        m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
        m_streamWriter.WriteLine("Service Stopped on " + DateTime.Now.ToLongDateString() + " at " + DateTime.Now.ToLongTimeString());
        m_streamWriter.WriteLine(" *----------------*");
        m_streamWriter.Flush();
        m_streamWriter.Close();

        tmr.Dispose();
    }

    private void goEXE(Object state)
    {
        Console.WriteLine(DateTime.Now.ToString());

        FileStream fs = new FileStream(@"c:\svclog.txt", FileMode.OpenOrCreate, FileAccess.Write);
        StreamWriter m_streamWriter = new StreamWriter(fs);
        m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
        m_streamWriter.WriteLine("Service running on " + DateTime.Now.ToLongDateString() + " at " + DateTime.Now.ToLongTimeString());
        m_streamWriter.WriteLine(" *----------------*");
        m_streamWriter.Flush();
        m_streamWriter.Close();

    }

    }
}
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激!

斯特凡诺

Nei*_*ell 6

你没有处置你的FileStream.垃圾收集器可以Dispose()为您调用,但它是非确定性的(即您不知道何时/是否会发生).这可能决定不要打扰.因此,建议的最佳实践是考虑包装IDisposableusing语句中实现的任何内容:

using (FileStream fs = new FileStream(@"c:\svclog.txt", FileMode.OpenOrCreate, FileAccess.Write)
{
    using (using (StreamWriter m_streamWriter = new StreamWriter(fs)))
    {
        m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
        m_streamWriter.WriteLine("Service Started on " + DateTime.Now.ToLongDateString() + " at " + DateTime.Now.ToLongTimeString());
        m_streamWriter.WriteLine(" *----------------*");
    }
}
Run Code Online (Sandbox Code Playgroud)

出于维护和干燥的原因,您还应该考虑将文件编写代码重构为单独的方法:

private void Log(string message)
{
    using (FileStream fs = new FileStream(@"c:\svclog.txt", FileMode.OpenOrCreate, FileAccess.Write)
    {
        using (using (StreamWriter m_streamWriter = new StreamWriter(fs)))
        {
            m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
            m_streamWriter.WriteLine(message + " " + DateTime.Now.ToLongDateString() + " at " + DateTime.Now.ToLongTimeString());
            m_streamWriter.WriteLine(" *----------------*");
        }
    }
}

protected override void OnStart(string[] args)
{
    Log("Service Started");

    tmrCallBack = new TimerCallback(goEXE);
    tmr = new Timer(tmrCallBack, null, 0, 1000 * 60 * 1 / 2);
}

protected override void OnStop()
{
    Log("Service Stopped");

    tmr.Dispose();
}

private void goEXE(Object state)
{
    Console.WriteLine(DateTime.Now.ToString());

    Log("Service running");
}
Run Code Online (Sandbox Code Playgroud)