using System;
using System.Collections.Generic;
using System.Text;
using System.Timers;
using System.Data;
using System.Data.SqlClient;
using System.DirectoryServices;
using System.Net;
using System.Net.Sockets;
using System.IO;namespace test
{
    public class sendIsoTask
    {
        private string tempPath;
        private System.Timers.Timer st;
        private int inTimerSendFlag = 0;
        public void Start()
        {
            string temp = System.Environment.GetEnvironmentVariable("TEMP");
            DirectoryInfo info = new DirectoryInfo(temp);
            tempPath = info.FullName;            st = new System.Timers.Timer(10000);
            st.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
            st.AutoReset = true;
            st.Enabled = true;
        }        protected void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
        {
            if (inTimerSendFlag == 0)//避免Timer重路
            {
                inTimerSendFlag = 1;
                String SqlConStr = string.Format("data source={0};initial catalog={1};password={2};user id={3}", "192.168.1.4", "iso", "123", "sa");
                SqlConnection SqlCon = new SqlConnection(SqlConStr);
                SqlConnection SqlAddCon = new SqlConnection(SqlConStr);
                SqlCon.Open();                //发送信息
                SendCheckMsg(SqlCon, SqlAddCon);////即使这里注释掉,内存仍不断增加
                SendApproveMsg(SqlCon, SqlAddCon);////即使这里注释掉,内存仍不断增加
                清除已发送记录
                SendDel(SqlCon);////即使这里注释掉,内存仍不断增加                SqlCon.Close();
                SqlCon.Dispose();
                SqlAddCon.Dispose();
                inTimerSendFlag = 0;
            }
        }        /// <summary>
        /// 发送审核通知
        /// </summary>
        /// <param name="SqlCon"></param>
        private void SendCheckMsg(SqlConnection SqlCon, SqlConnection SqlAddCon)
        {
            string SqlQuery = @"SELECT ff.FileNo,ff.FileID, ff.FileName, pu.LoginName
                                FROM   fcFileHistory AS fh INNER JOIN
                                       fcFile AS ff ON fh.FileNo = ff.FileNo INNER JOIN
                                       fcFileRight AS fr ON fh.FileNo = fr.FileNo AND fr.CheckRight = 1
                                       INNER JOIN pbUser as pu on fr.UserNo = pu.UserNo
                                WHERE  (fh.CheckNo IS NULL)
                                   AND (fh.FileNo NOT IN
                                                          (SELECT FileNo
                                                            FROM  fetionMSG_Check))";
            SqlCommand SqlCmd = new SqlCommand(SqlQuery, SqlCon);
            SqlDataReader SqlReader = SqlCmd.ExecuteReader();            while (SqlReader.Read())
            {
                try
                {
                    string UserNo = getADUserMobile(SqlReader[3].ToString());
                    String taskMSG = string.Format("{0}^在《ISO文件控制系统》中有一个文件等待您的审核,文件编号《{1}》,文件名《{2}》^0", UserNo, SqlReader[1].ToString(), SqlReader[2].ToString());
                    if (SendMsg(taskMSG))//发送信息
                        AddCheckSended((int)SqlReader[0], SqlAddCon);//发送后将已发送的添加到已发送列表,列表每日清空一次,也就是说任务提醒后当天没处理完,隔天会再次发送
                }
                catch (Exception ex)
                {
                    //Console.WriteLine("审核消息:" + ex.Message);
                    WriteLog("审核消息:" + ex.Message);
                }
                //break;
            }            SqlReader.Close();
            SqlReader.Dispose();
            SqlCmd.Dispose();
        }        /// <summary>
        /// 发送批准通知
        /// </summary>
        /// <param name="SqlCon"></param>
        private void SendApproveMsg(SqlConnection SqlCon, SqlConnection SqlAddCon)
        {
            string SqlQuery = @"SELECT ff.FileNo, ff.FileID, ff.FileName, pu.LoginName
                                FROM   fcFileHistory AS fh INNER JOIN
                                       fcFile AS ff ON fh.FileNo = ff.FileNo INNER JOIN
                                       fcFileRight AS fr ON fh.FileNo = fr.FileNo AND fr.ApproveRight = 1
                                       INNER JOIN pbUser as pu on fr.UserNo = pu.UserNo
                                WHERE  (fh.ApproveNo IS NULL) 
                                   AND (fh.FileNo NOT IN
                                                          (SELECT fh1.FileNo
                                                            FROM  fcFileHistory AS fh1 INNER JOIN
                                                                  fcFile AS ff1 ON fh1.FileNo = ff1.FileNo INNER JOIN
                                                                  fcFileRight AS fr1 ON fh1.FileNo = fr1.FileNo AND fr1.CheckRight = 1
                                                            WHERE (fh1.CheckNo IS NULL))) 
                                   AND (fh.FileNo NOT IN
                                                          (SELECT FileNo
                                                            FROM  fetionMSG_Approve))";            SqlCommand SqlCmd = new SqlCommand(SqlQuery, SqlCon);
            SqlDataReader SqlReader = SqlCmd.ExecuteReader();            while (SqlReader.Read())
            {
                try
                {
                    string UserNo = getADUserMobile(SqlReader[3].ToString());
                    String taskMSG = string.Format("{0}^在《ISO文件控制系统》中有一个文件等待您的批准,文件编号《{1}》,文件名《{2}》^0", UserNo, SqlReader[1].ToString(), SqlReader[2].ToString());
                    if (SendMsg(taskMSG))//发送信息
                        AddApproveSended((int)SqlReader[0], SqlAddCon);//发送后将已发送的添加到已发送列表,列表每日清空一次,也就是说任务提醒后当天没处理完,隔天会再次发送
                }
                catch (Exception ex)
                {
                    //Console.WriteLine("批准消息:" + ex.Message);
                    WriteLog("批准消息:" + ex.Message);
                }
                //break;
            }            SqlReader.Close();
            SqlReader.Dispose();
            SqlCmd.Dispose();
        }        /// <summary>
        /// 获取帐号对应域帐号手机号码
        /// </summary>
        /// <param name="UserNo"></param>
        /// <returns></returns>
        private string getADUserMobile(string UserNo)
        {
            try
            {
                DirectoryEntry su = new DirectoryEntry("LDAP://192.168.1.2/OU=gongsi,DC=ssss,DC=local", "[email protected]", "123");
                DirectorySearcher searcher = new DirectorySearcher();
                searcher.SearchRoot = su;
                searcher.Filter = "(&(objectClass=user)(sAMAccountName=" + UserNo + "))";
                searcher.SearchScope = SearchScope.Subtree;
                searcher.Sort = new SortOption("givenName", System.DirectoryServices.SortDirection.Ascending);
                SearchResultCollection results = searcher.FindAll();                foreach (SearchResult sr in results)
                {
                    return sr.Properties["mobile"][0].ToString().Trim();//取手机号码
                }
            }
            catch (Exception e)
            {
                //域验证失败
                WriteLog("取手机号出错:" + e.Message);
            }
            return "";
        }        /// <summary>
        /// 使用发送路由FetionRouter发送信息
        /// </summary>
        /// <param name="taskMSG">提交给FetionRouter的信息,格式:phone^msg^sendtype</param>
        private Boolean SendMsg(string taskMSG)
        {
            TcpClient client = null;
            NetworkStream stream = null;
            string sSerMsg = "0";
            try
            {                client = new TcpClient();
                client.Connect("192.168.1.3", 1860);
                stream = client.GetStream();
                byte[] rBuffer = Encoding.UTF8.GetBytes(taskMSG);
                stream.Write(rBuffer, 0, rBuffer.Length);
                byte[] sBuffer = new byte[1024];
                int received = stream.Read(sBuffer, 0, 1024);
                sSerMsg = Encoding.UTF8.GetString(sBuffer).Trim('\0');
                switch (sSerMsg)
                {
                    case "1":
                        WriteLog("发送手机号码没有在手机号和飞信号的对应列表里面《原信息:" + taskMSG + "》");
                        break;
                    case "2":
                        WriteLog("发送的对象没有添加飞信机器人为好友《原信息:" + taskMSG + "》");
                        break;
                    case "3":
                        WriteLog("登陆用户名密码错误《原信息:" + taskMSG + "》");
                        break;
                    case "9":
                        WriteLog("未知错误《原信息:" + taskMSG + "》");
                        break;
                }
            }
            catch (SocketException ex)
            {
                //Console.WriteLine(ex.Message);
                WriteLog("发送:" + ex.Message);
            }
            finally
            {
                if (client != null)
                {
                    client.Close();
                    client = null;
                }                if (stream != null)
                {
                    stream.Close();
                    stream.Dispose();
                }
            }
            if (sSerMsg == "0")
                return true;
            else
                return false;
        }

解决方案 »

  1.   


            /// <summary>
            /// 添加当日已发送审核消息
            /// </summary>
            /// <param name="FileNo"></param>
            /// <param name="SqlCon"></param>
            private void AddCheckSended(int FileNo, SqlConnection SqlAddCon)
            {
                SqlAddCon.Open();
                string SqlQuery = "insert into fetionMSG_Check values(" + FileNo.ToString() + ",'" + DateTime.Today.ToString("yyyy-MM-dd") + "')";
                SqlCommand SqlCmd = null;
                try
                {
                    SqlCmd = new SqlCommand(SqlQuery, SqlAddCon);
                    SqlCmd.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    //Console.WriteLine("添加审核消息已发送:" + ex.Message);
                    WriteLog("添加审核消息已发送:" + ex.Message);
                }
                if (SqlCmd != null)
                {
                    SqlCmd.Dispose();
                }
                SqlAddCon.Close();
            }        /// <summary>
            /// 添加当日已发送批准消息
            /// </summary>
            /// <param name="FileNo"></param>
            /// <param name="SqlCon"></param>
            private void AddApproveSended(int FileNo, SqlConnection SqlAddCon)
            {
                SqlAddCon.Open();
                string SqlQuery = "insert into fetionMSG_Approve values(" + FileNo.ToString() + ",'" + DateTime.Today.ToString("yyyy-MM-dd") + "')";
                SqlCommand SqlCmd = null;
                try
                {
                    SqlCmd = new SqlCommand(SqlQuery, SqlAddCon);
                    SqlCmd.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    //Console.WriteLine("添加批准消息已发送:" + ex.Message);
                    WriteLog("添加批准消息已发送:" + ex.Message);
                }
                if (SqlCmd != null)
                {
                    SqlCmd.Dispose();
                }
                SqlAddCon.Close();
            }        private void SendDel(SqlConnection SqlCon)
            {
                int curHour = DateTime.Now.Hour;
                int curMinute = DateTime.Now.Minute;
                string tempDt = DateTime.Today.AddDays(-3).ToString("yyyy-MM-dd");//三天前
                if (curHour == 23 && curMinute > 50)
                {
                    string SqlQuery = "delete from fetionMSG_Check where SendTime <= '" + tempDt + "';delete from fetionMSG_Approve where SendTime <= '" + tempDt + "'";
                    SqlCommand SqlCmd = null;
                    try
                    {
                        SqlCmd = new SqlCommand(SqlQuery, SqlCon);
                        SqlCmd.ExecuteNonQuery();
                    }
                    catch (Exception ex)
                    {
                        //Console.WriteLine("添加批准消息已发送:" + ex.Message);
                        WriteLog("清除发送记录出错:" + ex.Message);
                    }
                    if (SqlCmd != null)
                    {
                        SqlCmd.Dispose();
                    }
                }
            }        /// <summary>
            /// 写日志
            /// </summary>
            /// <returns></returns>
            private bool WriteLog(string msg)
            {
                FileStream fs = null;
                StreamWriter sw = null;
                bool ret = true;
                try
                {
                    string FileName = "";
                    FileName = tempPath + "\\log" + DateTime.Now.ToString(".yyyMMdd");                //CHECK文件存在不                   if (!File.Exists(FileName))
                    {
                        FileStream tempfs = File.Create(FileName);
                        tempfs.Close();
                    }                fs = new FileStream(
                        FileName,
                        FileMode.Append,
                        FileAccess.Write,
                        FileShare.None);                fs.Seek(0, System.IO.SeekOrigin.End);
                    sw = new StreamWriter(fs, System.Text.Encoding.UTF8);
                    sw.WriteLine(msg);                if (sw != null)
                    {
                        sw.Close();
                        sw = null;
                    }                if (fs != null)
                    {
                        fs.Close();
                        fs = null;
                    }
                }
                catch (Exception)
                {
                    ret = false;
                }
                finally
                {
                    try
                    {
                        if (sw != null)
                        {
                            sw.Close();
                            sw = null;
                        }
                        if (fs != null)
                        {
                            fs.Close();
                            fs = null;
                        }
                    }
                    catch
                    {
                    }
                }
                return ret;
            }        public void Stop()
            {
                st.Enabled = false;
            }
        }
    }
      

  2.   

    http://topic.csdn.net/t/20040422/11/2995313.html
      

  3.   

    你10s就执行下以下代码就够呛,可不可以弄成静态的?这里只open
    String SqlConStr = string.Format("data source={0};initial catalog={1};password={2};user id={3}", "192.168.1.4", "iso", "123", "sa");
                    SqlConnection SqlCon = new SqlConnection(SqlConStr);
                    SqlConnection SqlAddCon = new SqlConnection(SqlConStr);
                    SqlCon.Open();
      

  4.   

    不要每次都打开数据库连接看看呢
    做全局的连接
    恐怕是不断创建数据库对象引起的
    虽然你dispose了 但是对象也不是立即回收的
      

  5.   

    要坚定不移的多使用using(){}.
    你可能有一个重大误区,任何程序的内存使用图形都不是平稳的,一条直线。       +---+  +---+    +---+   <- 应用程序最高内存使用峰值
           |   |  |   |    |   |   <- 中间的过程可能会有陡坡的样式,看来很吓人,不过不用过分担心
           |   |  |   |    |   |
    ------+   +--+   +----+   +--- <-GC 收集后的内存使用数字,这个数字最重要。GC 使用后的内存数字,要基本平衡,在几小时,几天 内要保持一条直线。 应用程序就没有问题。 如果底边这条线越来越高,说明程序真的有泄漏。 
      

  6.   

    代码已调整,内在仍然不断增加。    public class sendIsoTask
        {
            private string tempPath;
            private System.Timers.Timer st;
            private int inTimerSendFlag = 0;
            private SqlConnection SqlCon;
            private SqlConnection SqlAddCon;        public void Start()
            {
                string temp = System.Environment.GetEnvironmentVariable("TEMP");
                DirectoryInfo info = new DirectoryInfo(temp);
                tempPath = info.FullName;            String SqlConStr = string.Format("data source={0};initial catalog={1};password={2};user id={3}", "192.168.2.250", "iso9000", "ssgas.com.cn?87735123", "sa");
                SqlCon = new SqlConnection(SqlConStr);
                SqlAddCon = new SqlConnection(SqlConStr);            st = new System.Timers.Timer(10000);
                st.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
                st.AutoReset = true;
                st.Enabled = true;
            }        protected void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
            {
                if (inTimerSendFlag == 0)//避免Timer重路
                {
                    inTimerSendFlag = 1;
                    SqlCon.Open();                //发送信息
                    SendCheckMsg();
                    SendApproveMsg();
                    //清除已发送记录
                    SendDel();                SqlCon.Close();
                    inTimerSendFlag = 0;
                }
            }
        }
    }
      

  7.   

    数据库连接部分可以使用Singleton 模式或者static 。全局单一实例。不需要重复创建和销毁
      

  8.   

    .net程序性能分析 你用DotTrace吧
    可以监控你的cpu和内存都被谁给用掉了
    这种情况只要看看内存中哪个类型的对象占用的内存越来越大就ok了
      

  9.   

    代码我没有细看,但我总担心你陷入一个误区, 你不太了解内存使用模型你可以用.net memory profiler 测试一下。http://www.colinfahey.com/dotnet/dot_net_memory_profiler_graph.gifGC 收集后的内存使用量不增长,程序就是可以的
      

  10.   

    线程同步protected void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
            {
                if(Monitor.TryEnter(this.GetType()))
                 {
                     ....................                 Monitor.Exit(this.GetType());
                  }
            }
      

  11.   

    system.threading.timer
    用这个试试
      

  12.   

    Timer用线程实现,一个线程要近10M
      

  13.   

    一. 确认泄漏类型;
    用性能监视器看看吧,针对需要检测的进程添加三个计数器:
    process : 
      1. Private bytes;
      2. Virtual bytes;.Net Memory:
      Bytes in all Heaps.即可以看到到底有没有泄漏;二. 用 DebugDiag 自动分析泄漏点.
      

  14.   

    1、代码编写方面,建议使用楼上兄弟说的,用 Using(){} 将需要释放的代码包裹起来;
    2、对于链接资源最好事先 IDisposiable 模式;
    3、分析泄漏点,采用 DebugDiag 自动分析即可。
      

  15.   

    用using块
    using(SqlConnection SqlCon = new SqlConnection(SqlConStr)
    {
    ....
    }
    另一个,每次都new一个,虽然释放了,但还没被垃圾回收
    要么每次你都强制垃圾回收GC.Collect()
    要么最好只new一个
      

  16.   

    不关sql的事..这只是GC Collector 回收的频率赶不上timer的频率 ,如果在每次触发的时候使用大量内存资源的时候尤其明显.如果你用线程的话使用threadpool估计能好一些.
      

  17.   

    修改下这里试试,在每次定时事件执行后就强制回收一下资源。 
           protected void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
            {
                if (inTimerSendFlag == 0)//避免Timer重路
                  {
                    inTimerSendFlag = 1;
                    SqlCon.Open();                //发送信息
                      SendCheckMsg();
                    SendApproveMsg();
                    //清除已发送记录
                      SendDel();                SqlCon.Close();                //强制垃圾回收
                      GC.Collect();
                    GC.WaitForFullGCComplete();
                    GC.Collect();                inTimerSendFlag = 0;
                }
            }
      

  18.   

    我建议LZ读下这个
    http://www.cnblogs.com/artech/archive/2009/12/03/1616507.html
      

  19.   

    就算直接调用了GC.Collect() 它也不是马上就给你回收 并且直接调用好像很影响效率
      

  20.   

    用System。Threading.Monitor来实现同步
      

  21.   

    1、ontimer里最好这样来写:
    try
    {
    timer.enable=false;
    //操作。}
    finally
    {
    timer.enable=true;
    }
    2、像楼上几位大侠们讲的,不要频繁的开/关数据库连接,做个全局的吧;
    3、是不是界面的原因引起的内存使用过高呢?比如:没有定时清空控件的内容,只是向控件不断的加内容
      

  22.   

    强制回收已添加
    system.threading.timer也试过
    数据库连接做了全局的内存仍然持续上涨........
      

  23.   

    就算我把timer事件里边的代码都去掉,内存仍不断上涨,只不过涨的慢点
      

  24.   

    挺奇怪的,不负责的话就不多说了,你确定下面三处同时注释掉还会内存不断增加吗?
                    SendCheckMsg(SqlCon, SqlAddCon);////即使这里注释掉,内存仍不断增加
                    SendApproveMsg(SqlCon, SqlAddCon);////即使这里注释掉,内存仍不断增加                SendDel(SqlCon);////即使这里注释掉,内存仍不断增加
    如果什么事都不做,没理由会增加的。单单执行了SqlCon.Open();不至于会那样,除非还有隐藏代码,为了保护代码机密。
      

  25.   

    话又说回来了,那个sendIsoTask类只提供了启动函数Start(),并不是主函数Main,有可能你是主函数调用实出了问题,比如使用循环实例化了多个sendIsoTask类。
      

  26.   

    都去掉也持续增长
    没有隐藏代码,只有调用此类的代码没贴出来,本来系统是做成服务的,但服务调试不了,所以在此处我是使用的控制台程序调用的,如下所示:using System;
    using System.Collections.Generic;
    using System.Text;namespace test
    {
        class Program
        {
            static void Main(string[] args)
            {
                sendIsoTask sit = new sendIsoTask();
                sit.Start();
                Console.WriteLine("Hit return to exit");
                Console.ReadLine();
                sit.Stop();
            }
        }
    }