C# 写的服务运行一段时间就崩溃了,日志显示 event 7031

xieqi 2009-05-26 10:48:10
怎样会引起event 7031事件?
这个服务一开始不会崩溃的,就是我加了一个
System.Threading.Timer m_Timer5 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function5), null, 0, 3000);
就开始崩溃了。不定期,一天崩溃10次吧。这个程序都catch了错误,根本catch不到。原来的程序有4个这样的语句
System.Threading.Timer m_Timer1 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function1), null, 0, 60000);
。。。
一直到
System.Threading.Timer m_Timer4 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function4), null, 0, 60000);
都没问题。只是加了个m_Timer5 ,就开始崩溃了。

后来我把my_function5方法简化了,只有一个写静态文件的,打印当前时间,还是会不定期崩溃。
后来我把my_function5方法改成空方法了,就不崩溃了。后来我把循环时间改成20秒(原来是3秒),运行一晚上也没崩溃。
我遇到这问题不知道如何去找问题,只好一点点试,很郁闷。
推测应该和程序压力有关,这个是remoting服务程序,一样的程序装了10台机器,访问压力小的服务器,崩溃次数少,崩溃次数和访问压力成正比。

现在就不知道,怎么会引发event 7031事件。
...全文
1027 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
Holly 2009-05-26
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 xieqi 的回复:]
有共享资源的。但是我把新加的Timer5去掉运行就没问题。
而Timer5只是每3秒,在一个文件记录当前时间,都会崩溃。
[/Quote]
共享资源的访问是用什么方法互斥的呢?
新增的3秒的Timer写的文件本身是否也是共享的资源之一?
xieqi 2009-05-26
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 isjoe 的回复:]
System.Threading.Timer这种计时器是线程池方式,不知道你是否考虑过这个问题。
[/Quote]
线程池有什么问题呢?
xieqi 2009-05-26
  • 打赏
  • 举报
回复
有共享资源的。但是我把新加的Timer5去掉运行就没问题。
而Timer5只是每3秒,在一个文件记录当前时间,都会崩溃。
Holly 2009-05-26
  • 打赏
  • 举报
回复
你的5个Timer中是否有共享访问的资源?
这部分资源的访问的代码是如何实现的?
isjoe 2009-05-26
  • 打赏
  • 举报
回复
System.Threading.Timer这种计时器是线程池方式,不知道你是否考虑过这个问题。
xieqi 2009-05-26
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 Holly 的回复:]
你的代码真的是这样写的吗?

public class Remoting_function : System.MarshalByRefObject
{
public static System.Threading.Timer m_Timer1, m_Timer2, m_Timer3, m_Timer4,m_Timer5;

public static void MainPro(object o)
{
System.Threading.Timer m_Timer1 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function1), null, 0, 3000);
System.Threading.Timer m_Timer2 …
[/Quote]
红色部分没有的。没抄好。
public static void MainPro(object o)
{
m_Timer1 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function1), null, 0, 3000);
m_Timer2 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function2), null, 0, 3000);
m_Timer3 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function3), null, 0, 3000);
m_Timer4 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function4), null, 0, 3000);
m_Timer5 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function5), null, 0, 3000);
}
Holly 2009-05-26
  • 打赏
  • 举报
回复
建议你做一下CodeReview,检查一下是否在代码中有其他的地方有这种写法,这会导致变量的生命周期混乱。
Holly 2009-05-26
  • 打赏
  • 举报
回复
你的代码真的是这样写的吗?

public class Remoting_function : System.MarshalByRefObject
{
public static System.Threading.Timer m_Timer1, m_Timer2, m_Timer3, m_Timer4,m_Timer5;

public static void MainPro(object o)
{
System.Threading.Timer m_Timer1 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function1), null, 0, 3000);
System.Threading.Timer m_Timer2 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function2), null, 0, 3000);
System.Threading.Timer m_Timer3 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function3), null, 0, 3000);
System.Threading.Timer m_Timer4 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function4), null, 0, 3000);
System.Threading.Timer m_Timer5 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function5), null, 0, 3000);
}
}
注意红色的部分,当你这样写,直接的结果是,在构造函数中为5个临时变量赋值,而不是class的成员变量
这样子程序当然可以运行,因为.net的垃圾回收机制是不定期回收的,当程序的资源消耗不严重的时候,Framework不会频繁回收垃圾,当你的负载多了以后,垃圾回收机制会更加的频繁启动,每次回收,都可能导致Timer的销毁,你的程序当然有可能产生崩溃。

xieqi 2009-05-26
  • 打赏
  • 举报
回复
public class Remoting_function : System.MarshalByRefObject
{
public static System.Threading.Timer m_Timer1, m_Timer2, m_Timer3, m_Timer4,m_Timer5;

public static void MainPro(object o)
{
System.Threading.Timer m_Timer1 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function1), null, 0, 3000);
System.Threading.Timer m_Timer2 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function2), null, 0, 3000);
System.Threading.Timer m_Timer3 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function3), null, 0, 3000);
System.Threading.Timer m_Timer4 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function4), null, 0, 3000);
System.Threading.Timer m_Timer5 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function5), null, 0, 3000);
}
}
=====================
MainPro(object o)是服务一起动,就开始运行的。在serviceStart里。

class Remoting
{
public static System.Threading.Timer m_Timer1;
public void serviceStart()
{
channel = new TcpServerChannel(56125);
ChannelServices.RegisterChannel(channel);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Remoting_function), "Remoting_function", WellKnownObjectMode.Singleton);

channel1 = new TcpServerChannel("tcp1",56126);
ChannelServices.RegisterChannel(channel1);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Remoting_function), "Remoting_function", WellKnownObjectMode.Singleton);
//我侦听了2个端口。
m_Timer1 = new System.Threading.Timer(new System.Threading.TimerCallback(Remoting_function.MainPro), null, sleep_time, 0);
}
}
以前一直不崩溃,或2,3个月偶然崩溃一次的。
我加了System.Threading.Timer m_Timer5 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function5), null, 0, 3000);
就1天崩溃10几次。太不正常了。我的服务器是4核,难道4个cup调度5个线程调度不过来就崩溃了?
不过新加的线程是3秒循环一次,以前4个都是间隔比较长,60秒到600秒不等。
新加的线程间隔20秒,一晚上也没问题,看来可能还是程序压力大。
shalen520 2009-05-26
  • 打赏
  • 举报
回复
当Service Control Manager 侦测到有服务非正常退出,就会产生此event id,详见:http://www.eventid.net/display.asp?eventid=7031&eventno=465&source=Service%20Control%20Manager&phase=1

个人认为是你的服务运行过程中有未处理的异常,考虑加入异常捕获代码,并打印出日志和堆栈以方便定位问题
Holly 2009-05-26
  • 打赏
  • 举报
回复
需要知道你的程序结构,这几个Timer都是在什么位置声明,什么时候开始运行,什么情况结束,什么时候释放资源?
xieqi 2009-05-26
  • 打赏
  • 举报
回复
日志描述:
Description The <service name> service terminated unexpectedly. It has done this <n> time(s). The following corrective action will be taken in <no of ms> milliseconds: <action>.
wartim 2009-05-26
  • 打赏
  • 举报
回复
改用线程吧,
timer计时器如果用的是多个,它们不是完全独立运行的,
也就是说
System.Threading.Timer m_Timer1 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function1), null, 0, 60000);
System.Threading.Timer m_Timer2 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function1), null, 0, 60000);
System.Threading.Timer m_Timer3 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function1), null, 0, 60000);
System.Threading.Timer m_Timer4 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function1), null, 0, 60000);

你都设置为1分钟触发一次,而且内部的语句的执行时间肯定都少于1分钟

System.Threading.Timer m_Timer5 = new System.Threading.Timer(new System.Threading.TimerCallback(my_function5), null, 0, 3000);
3秒就触发一次,但如果m_Timer1~m_Timer4中任何一个在3秒钟内还没处理完,那m_Timer5到了3秒也不会触发,而是等待,处于堵塞状态,总处于不停触发和堵塞的状态就容易崩溃

简单举个例子
一个计时器 1秒触发一次
另一个计时器 3秒触发一次
然后1秒的那个里面执行了10秒,比如用sleep(10000)
那3秒那个也会排队等到10秒后才执行,
zhaoweiting0609 2009-05-26
  • 打赏
  • 举报
回复
up
xieqi 2009-05-26
  • 打赏
  • 举报
回复
找到问题了。
try
{...}
catch(Exception error1)
{这里有异常}
yingzhilian2008 2009-05-26
  • 打赏
  • 举报
回复
Up
xieqi 2009-05-26
  • 打赏
  • 举报
回复
The MY_Remoting service terminated unexpectedly. It has done this 1 time(s). The following corrective action will be taken in 60000 milliseconds: NO taken
Status里的该服务状态变成空了,就像这个服务停了或没开时的状态一样。

我现在改成Restart the service.
所以每次遇到这个情况就自动重启服务了
bbbbbb888888 2009-05-26
  • 打赏
  • 举报
回复
最好排队...线程是有限的.
xieqi 2009-05-26
  • 打赏
  • 举报
回复
to:Holly
不知道说崩溃恰当不恰当。我的现象就是服务启动后,在服务器列表的Status列里看到该服务的状态时Started。
但是过一段时间,Status里的该服务状态变成空了,就像这个服务停了或没开时的状态一样。
然后看系统日志,就会有个event 7031事件。
The MY_Remoting service terminated unexpectedly. It has done this 1 time(s). The following corrective action will be taken in 60000 milliseconds: Restart the service.

另外我用Timer是要间隔60秒做有些任务,有几种任务,间隔时间不同,有的要平凡一点,有的间隔大一点。
还能用什么方法来间隔几秒做某个事情呢。
(任务主要是计数等,要是每次打开正文都在数据库update set num=num+1 的话,数据库性能吃紧。现在就每次打开页面在内存里+1,10分钟后,那内存里的数据一次性update到数据库。还有灾难恢复机制,每隔5分钟,把最新的多少内容生成到静态文件之类的)
Holly 2009-05-26
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 xieqi 的回复:]
引用 10 楼 xieqi 的回复:
有共享资源的。但是我把新加的Timer5去掉运行就没问题。
而Timer5只是每3秒,在一个文件记录当前时间,都会崩溃。

但是我把间隔改成20秒,到现在大半天了,还没崩溃,到下午访问高峰时在看看,如果没崩溃,那还是和程序的压力有关,他处理不过来了,就崩溃了。
[/Quote]
这个观点似乎站不住脚,写服务程序是不能崩溃的,崩溃意味着意料之外的代码流程,如果是压力问题,通常只意味着缓慢,而不是崩溃。
另外不知道你的程序为什么需要这么多的Timer,通常都是线程池来处理。因为通常Timer都比线程消耗的资源要大很多。
感觉这个服务器的架构设计需要改良。
加载更多回复(3)

111,125

社区成员

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

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

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