asp.net application_start事件里开启线程的问题

问题描述

各位好,目前项目需要做一个数据同步的功能,而且是自动同步。我在application_start事件中添加了如下代码:protectedvoidApplication_Start(){.....//读取配置等代码AreaRegistration.RegisterAllAreas();//默认情况下对EntityFramework使用LocalDBDatabase.DefaultConnectionFactory=newSqlConnectionFactory(@"DataSource=(localdb)v11.0;IntegratedSecurity=True;MultipleActiveResultSets=True");Logger.ConfigureLog4Net(HttpContext.Current.Server.MapPath("~/log"),LogLevel.Info,LogLevel.Info);RegisterGlobalFilters(GlobalFilters.Filters);RegisterRoutes(RouteTable.Routes);//如果是平台,则启动,如果是控制中心,则不启动if(Application[SYSTEM_TYPE].ToString()=="1"){//判断平台类型if(!threadStarted){//线程是否已经启动infoTaskIdList=newList<int>();processTask=newProcessTask();threadProcessTask=newThread(newParameterizedThreadStart(processTask.ProcessTasks));threadProcessTask.Start(Application);开启线程。threadStarted=true;}}}

ProcessTasks方法如下:publicvoidProcessTasks(objectapplicationState){HttpApplicationStateapplication=applicationStateasHttpApplicationState;while(true){IEnumerable<Da_Task>taskList=taskBll.GetListByPage("andnvl(dt_status,'1')='1'","asc",0,20);if(taskList==null){continue;}taskList=taskList.OrderBy(p=>p.DT_ID);stringdealinfo="";foreach(Da_TasktaskintaskList){try{//保存Application全局UserID;这里会不会有问题?application["userid"]=task.DT_RCRE_USER;//模拟发送POST/GET请求,以便执行数据操作stringretstr=PostData(localHost+task.DT_Destination,task.DT_Data);IDictionary<string,JToken>parsedObject=null;try{parsedObject=JsonConvert.DeserializeObject(retstr)asJObject;}catch{parsedObject=JsonConvert.DeserializeObject("{result:-3}")asJObject;}//业务逻辑代码省略......}catch(Exceptione){//写错误日志,停止任务执行Loggerlog=Logger.GetLogger(this.GetType());log.Error("执行任务时发生错误",e);//break;}}Thread.Sleep(ProcessTaskTime);//执行完毕等待}}

现在的情况是这样的,我使用的是VS2012,框架是MVC,我配置的是调试使用本地IIS,而不是IISExpress,但是当我调试在ProcessTasks中断点时,发现有两个线程进入到该方法,导致调试出现问题,我猜想的原因是:一个线程是IIS的线程,另一个是我的调试线程。但是我疑惑的是Application_Start到底运行了几次???我已经通过threadStarted来判断,为什么还是有两条线程呢?请高手讲解??

解决方案

解决方案二:
网站天生是多线程的,你不要把网站当单机版玩
解决方案三:
application_start事件应该是只执行一次的啊……不懂了,就跟当初我怎么都抓不到application_end事件一样,完全不懂了
解决方案四:
application_start理论上的确是只运行一次但是网站在某些情况会自动重启然后再次调用application_start而线程却没有关闭所以会有两个线程
解决方案五:
threadStarted判断这里,尝试先lock一下,重入了,很可能是因为同事有2个线程调用了Application_Start而在threadStarted赋值之前,两个线程都进入了if判断,lock一下应该可以解决重入问题。另外多次调用Application_Start很可能是调试的原因,尝试打日志,软件直接在IIS上运行一下,可能就不会多次调用了。当然,IIS重启也是经常发生的事情。。。。。但是第一次就直接进入2次,应该可能性不是很大。下面这句是复制来的:你看下应用程序池属性里回收中回收工作进程和性能中空闲超时是否启用了?不想重复运行Application_Start就把复选框不要选中
解决方案六:
引用1楼Z65443344的回复:

网站天生是多线程的,你不要把网站当单机版玩

大神你这等于没说,我当然知道网站天生多线程,你要是知道一些端倪,烦请讲解一下,为什么我这调试时会有两个线程进入方法?使用IIS调试时,application_start执行了几次?
解决方案七:
Asp.net如果进程池被回收了,就会重新运行application_start所以就有可能运行多次。
解决方案八:
引用6楼wyd1520的回复:

Asp.net如果进程池被回收了,就会重新运行application_start所以就有可能运行多次。

按理说如果进程池被回收,则进程创建的线程也应该被回收才对啊,那就算重新启动应用运行application_start也应该还是一个线程。
解决方案:
引用7楼ZackHoo的回复:

Quote: 引用6楼wyd1520的回复:
Asp.net如果进程池被回收了,就会重新运行application_start所以就有可能运行多次。

按理说如果进程池被回收,则进程创建的线程也应该被回收才对啊,那就算重新启动应用运行application_start也应该还是一个线程。

进程池回收的不是他的整个进程不等于exe退出,是拉圾回收,一般会在进程池里面设定的内存达到一定的值时进程池开始回收,而你的线程是一直运行下去的,所以不会被回收。
解决方案:
!threadStarted你这个是静太对象?不是的话就是被回收执行完这个对象就没啥用了

时间: 2024-09-22 22:02:49

asp.net application_start事件里开启线程的问题的相关文章

asp.net在事件中启动线程来打开一个页面的实现方法_实用技巧

在页面点击一个按钮,其目的是在按钮中做两件事情,一件需要点击按钮马上完成,另一件事情是点击按钮后做其他事情.如果按顺序一次做完感觉特别耗时,下面简单罗列一下. protected void Button1_Click(object sender, EventArgs e) { Label1.Text = TextBox1.Text; //在这做第一件事情 dowork(); //做完后马上启动线程 System.Threading.Thread thread = new System.Threa

android 当在主线程里开启一个新线程 程序就崩溃

问题描述 android 当在主线程里开启一个新线程 程序就崩溃 我要实现的功能是检索SDcard里的所有txt文件我尝试过很多办法 1 不用线程 直接在主线程里检索文件 由于有循环且检索时间会超过5秒 导致黑屏然后提示未响应2 我建立一个线程让线程去检索文件当检索完毕后把检索到的文件传递给主类 主类再把检索到的文件显示在list上 但是当线程一启动程序就崩溃了3 最后我在主类里添加handler 当子线程检索完毕就sendmessage给主类 然后主类把子线程检索到的文件显示在list上但程序

关于多线程问题(新开启的线程里面再开启线程)

问题描述 先说下流程:首先运行主方法MainFun()这个方法会开启5个线程,每个线程调用DoSomething这方法,在DoSomething这个方法里面又会再开启线程(可能会开启多个),然后分别调用A.B.C.D.E5个方法.现在的问题是,我测试的时候,我用一个按钮的单击事件调用MainFun(),发现有时候程序会崩溃(什么错都不报直接关闭了),有时候正常运行,如果我按钮点快了是100%程序会崩溃的.求解决,多线程不会,改怎么解决,还是我写的有问题?主要代码如下:privatevoidMai

serial ort-一个cs里的SerialPort接收事件里,修改主程序label元素属性,不成功。

问题描述 一个cs里的SerialPort接收事件里,修改主程序label元素属性,不成功. 大家好,我是新手.请问,有两个cs,一个是SerialPort.cs,一个是Power.MainForm.cs.问题是在 SerialPort的接收事件里,修改主程序的label元素的属性,为什么不成功.代码如下. //serialPort.cs private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArg

android-Activity中开启线程进行耗时操作,怎么在Activity销毁时结束正在进行的线程

问题描述 Activity中开启线程进行耗时操作,怎么在Activity销毁时结束正在进行的线程 如题,在Android开发中,在activity中开启线程去执行耗时操作,有时候任务还没执行完Activity就被关闭了,有没有大神指导怎么在activity关闭的时候也杀死线程!有时候是多个线程使用线程池管理,怎么在activity销毁时关闭线程池里的所有线程!求高手指点迷津! 解决方案 1.线程里必须有办法退出 2.onResume里建立线程 3.onPause里设置线程结束标志结束线程 解决方

ASP.NET中事件如何依次发生?_实用技巧

本文通过实战的方法简单介绍ASP.NET中的事件执行顺序. 方法/步骤 新建C# WebForm项目,如下图: 在Defualt.aspx文件中添加一个Button控件并命名为Button1,然后为该控件各个事件添加事件处理程序,并添加断点,如下图: 打开Global.asax文件并添加断点,如下图: 打开Site.Master的代码文件Site.Master.cs,并添加断点,如下图: 按F5调试运行,查看代码运行顺序:Application_Start→Session_Start→Butto

PreInit事件 与 Init事件: 怎么两个事件里都进行控件属性的初始化?————————————————————————

问题描述 以下是在网上找到的资料:------------------------------------------------------1.PreInit()在这个页面级的事件中,所有在设计时创建的控件都将被用默认值做初始化.例如,如果你有一个Text属性值为"Hello"的TextBox控件,则此时这个属性被设置.我们也可以在这里动态的创建控件.2.Init()在所有控件都已初始化且已应用所有外观设置后触发,使用该事件来读取或初始化控件属性.------------------

sleep-MFC里的线程内Sleep()不执行???

问题描述 MFC里的线程内Sleep()不执行??? void CAaaDlg::OnButton1() { // TODO: Add your control notification handler code here m_a=0; SetTimer(1,500,NULL); } void CAaaDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default Upda

ASP.NET 2.0里动态访问META标记

asp.net|动态|访问 在asp.net 2.0里,可以支持动态访问meta 标记了,比如可以动态增加关键字了Private Sub CreateMetaTags()      Dim hm As New HtmlMeta()     Dim head As HtmlHead = CType(Page.Header, HtmlHead)     hm.Name = "Keywords"     hm.Content = "VB.Net, VB.NET, .NET"