Asp.net 由于异常,代码在线程池中执行了无限次

Asp.net 由于异常,代码在线程池中执行了无限次,asp.net,multithreading,threadpool,asp.net-4.0,Asp.net,Multithreading,Threadpool,Asp.net 4.0,我听说在asp.net中使用ThreadPool是不好的,但是我使用它是为了教育自己。我的目标是确定应用程序错误事件是否被触发(在Global.asax中处理)——我的答案是:不,它不会被触发 但我发现了一些奇怪的事情。我编写的线程只是将任务排队到线程池。该任务旨在随机抛出错误。但是,我观察到,我经常会收到错误——错误次数超过了我排队等待任务的次数。我还有一个问题,就是System.Diagnostics.Trace.WriteLine()没有将消息记录到我的输出窗口(visual studio

我听说在asp.net中使用ThreadPool是不好的,但是我使用它是为了教育自己。我的目标是确定应用程序错误事件是否被触发(在Global.asax中处理)——我的答案是:不,它不会被触发

但我发现了一些奇怪的事情。我编写的线程只是将任务排队到线程池。该任务旨在随机抛出错误。但是,我观察到,我经常会收到错误——错误次数超过了我排队等待任务的次数。我还有一个问题,就是
System.Diagnostics.Trace.WriteLine()
没有将消息记录到我的输出窗口(visual studio)。为什么会有这种奇怪的行为

using System;
using System.Threading;
namespace ThreadPoolDemo.Web
{
    public partial class _default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(createthreads);
            t.IsBackground = true;
            t.Start();
        }

        void createthreads()
        {
            Thread.Sleep(10 * 1000);
            int i;
            System.Diagnostics.Trace.WriteLine("Queueing items");
            for (i = 0; i < 1; i++)
                ThreadPool.QueueUserWorkItem(new WaitCallback(ErrorTask), null);
            System.Diagnostics.Trace.WriteLine("End Queueing items");
        }

        void ErrorTask(object obj)
        {
            Random generator = new Random();
            int value = generator.Next(1);            
            if (value == 0)
                throw new Exception("Sample exception thrown");
            else
                System.Diagnostics.Trace.WriteLine("Processed thread");
        }

    }
}
使用系统;
使用系统线程;
名称空间ThreadPoolDemo.Web
{
公共部分类\u默认值:System.Web.UI.Page
{
受保护的无效页面加载(对象发送方、事件参数e)
{
}
受保护的无效按钮1\u单击(对象发送者,事件参数e)
{
线程t=新线程(创建线程);
t、 IsBackground=true;
t、 Start();
}
void createthreads()
{
线程。睡眠(10*1000);
int i;
System.Diagnostics.Trace.WriteLine(“排队项”);
对于(i=0;i<1;i++)
QueueUserWorkItem(新的WaitCallback(ErrorTask),null);
System.Diagnostics.Trace.WriteLine(“结束排队项”);
}
无效错误任务(对象对象对象)
{
随机生成器=新随机();
int值=生成器。下一步(1);
如果(值==0)
抛出新异常(“抛出样本异常”);
其他的
系统.诊断.跟踪.写入线(“已处理线程”);
}
}
}

您的
错误任务有两个问题。首先,每次调用该方法时,您都会初始化一个新的
随机
实例。默认的
Random
构造函数使用
Environment.TickCount
中的值为随机数生成器种子,这对于连续线程可能是相同的。因此,对于多个线程,您将得到相同的随机序列


不过,更大的问题是
generator.Next(1)
将始终返回0
Random.Next(int max)
生成一个随机数N,这样
0感谢您提供的信息。这很有帮助。您在VS IDE中尝试过这个吗?它发生在IDE中。但是,在iis v5.1上,我发现每次发生异常时,
aspnet_wp.exe
进程都会死亡,并以另一个进程id重新出现。在事件日志中,有4个条目对应于单个异常,即我猜想的第一个异常。如果一个网站在web服务器上维护会话数据,我想这是不好的…@deocwalk:我没有试着运行你的代码。我的观察是基于对代码的检查。也许人们不鼓励在asp.net应用程序中使用线程池有一个很好的理由。
private Random generator = new Random();

void ErrorTask(object obj)
{
    int value;
    lock (generator)
    {
        value = generator.Next(2);
    }
    if (value == 0)
        throw new Exception("Sample exception thrown");
    else
        System.Diagnostics.Trace.WriteLine("Processed thread");
}