首页 新闻 会员 周边

请问这个方法有啥问题,iis上面开了一会儿后 iis就会报错。

0
悬赏园豆:10 [已解决问题] 解决于 2014-02-26 11:12

错误信息:

应用程序池 'hxemis' 被自动禁用,原因是为此应用程序池提供服务的进程中出现一系列错误。
为应用程序池 'XXX' 提供服务的进程在与 World Wide Web Publishing 服务通信时遇到致命错误-解决

 

//定时更新缓存
public void IntervalInit()
{
Thread t = null;
try
{
t = new Thread(() =>
{
while (true)
{
InitMessageCache();
System.Threading.Thread.Sleep(15 * 60 * 1000);//每个15分钟更新缓存
}
});
t.Start();
}
catch (Exception ex)
{
//Log...
if (t != null && t.IsAlive)
{
t.Abort();
}
t = new Thread(() =>
{
while (true)
{
System.Threading.Thread.Sleep(15 * 60 * 1000);//每个15分钟更新缓存
InitMessageCache();
}
});
t.Start();
}
}

 

我本地一台win2003不会报错

远程的2003之前的项目这样用也不会报错,这个项目用了 就报错了,上面的方法不用,就不会报错。求解释

yesyes的主页 yesyes | 初学一级 | 园豆:9
提问于:2013-12-03 14:43
< >
分享
最佳答案
0

不要调用 t.Abort()

你那个 try 也没用,它只能 catch 住 Thread 构造函数和 Start 方法抛出的异常。

线程内的异常,你应该在线程方法体或全局注册。

Thread 构造函数只会抛出 ArgumentNullException,所以如果构造出错了,那么你在 catch 中写的通常的代码在构造时还是会抛异常,这是没有用的。你仔细看你的代码,Thread 传入的构造参数是不可能为 null,所以你根本不需要 catch new Thread。

Thread.Start 方法会抛出 ThreadStateException 和 OutOfMemoryExcption,这和构造函数一样,看你代码,你的 t 是局部变量,不可能会被调用两次 Start 方法。如果没有足够内存启动此线程,那么你 catch 后再 new ,再 Start,它还是一样的结果。

总的来说,你的 catch 都是没有意义的,你要 catch 的是你的代码 InitMessageCache();因为你的逻辑里可能包含抛出不至于终止整个线程的错误,而你可以处理此异常,并恢复执行。

 

Thread t = null;
    t = new Thread(() = >
    {
        while (true)
        {
            try
            {
                InitMessageCache();
            }
            catch (CatchableException e1)
            {
                // 如果此异常可以处理,那么做一些错误处理,并继续执行。
            }
            catch (UncatchableException e2)
            {
                // 无法处理,程序必须结束,抛出此异常,这可能会终止整个进程。
                throw e2;
            }

            System.Threading.Thread.Sleep(15 * 60 * 1000);//每个15分钟更新缓存
        }
    });
    t.Start();

 

收获园豆:10
Launcher | 高人七级 |园豆:45045 | 2013-12-03 15:00

我在想  如果这样用呢?

 try
            {
                Timer timer = new Timer(InitMessageCache, null, 5000, 15 * 60 * 1000);
            }
            catch (Exception e)
            {
                LogHelper.SystemLog.Error(e);
            }
yesyes | 园豆:9 (初学一级) | 2013-12-03 15:36

@yesyes: 这样,你这个 try catch 还是没有用处,你的 try catch 一定要保护你的 InitMessageCache 方法,也就是说,如果你用 Timer 的话,你得这样改:

void InitMessageCache ()

{

   try {} catch().....

}

Launcher | 园豆:45045 (高人七级) | 2013-12-03 15:49

@Launcher:  谢谢您的热心帮助。

我一直觉得很奇怪。因为另一个项目用这个方法没报

应用程序池 'hxemis' 被自动禁用,原因是为此应用程序池提供服务的进程中出现一系列错误。
为应用程序池 'XXX' 提供服务的进程在与 World Wide Web Publishing 服务通信时遇到致命错误-解决

的错误。

这个又会是什么原因呢?

yesyes | 园豆:9 (初学一级) | 2013-12-03 15:56

@yesyes: 我没法给你的 IIS debug,所以我没法告诉你是什么原因引起了此错误,仅从文字描述来看——“进程中出现一系列错误”,我可以猜测,有可能是你的代码中抛出了太多未捕获的异常,而这些异常有些又是致命的,所以导致了你的进程被关闭。

Launcher | 园豆:45045 (高人七级) | 2013-12-03 16:07
其他回答(1)
0

楼上已经讲的很明白了,楼主的代码 只能捕获到 t.Start() 抛出的异常(可能因为系统资源不足等因素造成无法为你启动线程),而楼主又在catch中做了同样的事情 构造了一个新的thread,又去执行t.Start(),这样会造成递归。iis会将你的应用强制结束(你的应用程序池被禁用)。

 

总之一句话,错误千奇百怪,楼主只需要记住正确的做法就好了。

sylvester.lee | 园豆:238 (菜鸟二级) | 2013-12-03 23:21
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册