System.Timers.Timer不断地吃掉内存???(内附完整源码)

dhtkhnt 2009-12-03 04:56:54

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", "temp@ssss.local", "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;
}

...全文
3268 47 打赏 收藏 转发到动态 举报
写回复
用AI写文章
47 条回复
切换为时间正序
请发表友善的回复…
发表回复
acdyf 2012-07-05
  • 打赏
  • 举报
回复
[Quote=引用 44 楼 的回复:]

我找到问题了
谢谢
[/Quote]能不能把解决办法分享一下
dhtkhnt 2009-12-04
  • 打赏
  • 举报
回复
就算我把timer事件里边的代码都去掉,内存仍不断上涨,只不过涨的慢点
dhtkhnt 2009-12-04
  • 打赏
  • 举报
回复
强制回收已添加
system.threading.timer也试过
数据库连接做了全局的

内存仍然持续上涨........
ztenv 2009-12-04
  • 打赏
  • 举报
回复
1、ontimer里最好这样来写:
try
{
timer.enable=false;
//操作。。。。

}
finally
{
timer.enable=true;
}
2、像楼上几位大侠们讲的,不要频繁的开/关数据库连接,做个全局的吧;
3、是不是界面的原因引起的内存使用过高呢?比如:没有定时清空控件的内容,只是向控件不断的加内容
l171147904 2009-12-04
  • 打赏
  • 举报
回复
看楼主的 头像,,哪还有心情 看 代码!
jzywh 2009-12-04
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 jzywh 的回复:]
线程同步

protected void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
        {
            if(Monitor.TryEnter(this.GetType()))
            {
                ....................

                Monitor.Exit(this.GetType());
              }
        }

[/Quote]
用System。Threading.Monitor来实现同步
a6711145 2009-12-04
  • 打赏
  • 举报
回复
lZ 代码逻辑方面可能遗漏了什么。所以赵成了这个样子。
仔细检查下
kof_sdu 2009-12-04
  • 打赏
  • 举报
回复
就算直接调用了GC.Collect() 它也不是马上就给你回收 并且直接调用好像很影响效率
ViewStates 2009-12-04
  • 打赏
  • 举报
回复
Neil198 2009-12-04
  • 打赏
  • 举报
回复
qldsrx 2009-12-04
  • 打赏
  • 举报
回复
修改下这里试试,在每次定时事件执行后就强制回收一下资源。
       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;
}
}
cuike519 2009-12-04
  • 打赏
  • 举报
回复
已给楼主留言,请查收...
cuike519 2009-12-04
  • 打赏
  • 举报
回复
楼主莫急,待我建立好工程帮你看看。


理论上来说是不会的,但是实践是检验真理的唯一标准,待我检验检验啊。。。
wangan2008 2009-12-04
  • 打赏
  • 举报
回复
up
hyfzz123 2009-12-04
  • 打赏
  • 举报
回复
mark
dhtkhnt 2009-12-04
  • 打赏
  • 举报
回复
我运行了14小时,内存从35M 上升到162M了
晕掉
lijun_xiao2009 2009-12-04
  • 打赏
  • 举报
回复
dai78 2009-12-04
  • 打赏
  • 举报
回复
讲一下吗
dhtkhnt 2009-12-04
  • 打赏
  • 举报
回复
我找到问题了
谢谢
ProjectDD 2009-12-04
  • 打赏
  • 举报
回复
顶牛人BuilderC
学习
加载更多回复(26)

111,120

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧