为什么ASP.NET杀死我的后台线程? [英] Why ASP.NET kills my background thread?

查看:309
本文介绍了为什么ASP.NET杀死我的后台线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的code在我的codebehind(aspx.cs):

 保护无效的button1_Click(对象发件人,EventArgs的发送)
{
    新的Thread(委托(){
        尝试
        {
            Thread.sleep代码(30000); // 30秒无能为力
        }
        赶上(异常前)
        {
            //我AWLAYS在这里得到一个ThreadAbortException
            //在约1秒为什么!?!?!
        }    })。开始();
}

ASP.NET是否杀死所有的子线程的请求结束时?

PS。我predict了很多,因为它不是最好的做法的答案。我知道,在Windows服务运行的东西的最佳做法等我只是好奇的到底为什么线程要在这个特殊的code打死,因为没有的Response.Redirect没有到Response.End,没有池回收,没有IIS重启等等等等(典型原因的人重复着在ASP.NET中后台线程是坏的的口头禅)。

更新:事实证明它的工作在ASP.NET MVC精细!线程仅在Web的表单中止!!这更加怪异。任何想法?


解决方案

好了,48小时后在这里进行试验的是我发现的:

1。它的优良在ASP.NET运行后台线程的 _MVC _

如果你对MVC - 刚开始你的线程正常,他们将不会被当前请求结束后,中止:

  // MVC  - 工作得很好
公众的ActionResult ThreadTest()
{
    新的Thread(委托(){
        尝试
        {
            System.Threading.Thread.Sleep(10000);
        }
        赶上(异常前)
        {
            //没有会抛出异常
        }
    })。开始();
    返回内容(OK);
}

2。对于Web窗体 - 结合使用的BackgroundWorker与异步页面属性

我了解到,与web表单不能使用:


  • 新的Thread()启动()。 //不能正常工作


  • ThreadPool.QueueUserWorkItem //不能正常工作


  • Action.BeginInvoke //不能正常工作


  • 一堆其他的东西 - 所有不工作


下面是你需要做的:

1)标记您的页面中的.aspx异步(这会告诉ASP.NET来继承IAsyncHandler页)

 <%@页语言=C#异步=真正的%GT;

2)使用的BackgroundWorker在.aspx.cs

 保护无效的button1_Click(对象发件人,EventArgs的发送)
{
    VAR BG =新的BackgroundWorker();
    bg.DoWork + =代表
    {
        尝试
        {
            Thread.sleep代码(10000); // 10秒无能为力
        }
        赶上(异常前)
        {
            //没有excpeiton被抛出
        }    };
    bg.RunWorkerAsync();
}

3。如果你在.NET 4.5.2或更高版本 - 简单地使用 HostingEnvironment.QueueBackgroundWorkItem


  

的HostingEnvironment.QueueBackgroundWorkItem方法可以让你
  安排小型背景的工作项目。 ASP.NET跟踪这些项目和
  prevents从突然终止工作进程,直到所有的IIS
  后台工作项目已经完成。这种方法不能被称为
  外面一个ASP.NET管理应用程序域。


荣誉给@丹尼 - tuppeny这最后一个

I have the following code in my codebehind (aspx.cs):

protected void button1_Click(object sender, EventArgs e)
{
    new Thread(delegate() {
        try
        {
            Thread.Sleep(30000); //do nothing for 30 seconds
        }
        catch (Exception ex)
        {
            //I AWLAYS get a ThreadAbortException here
            //in about 1 second WHY!?!??!
        }

    }).Start();
}

Does ASP.NET kill all child threads when the request ends?

PS. I predict a lot of "because it's not best practice" answers. I know about best practices of running things in a windows service etc. I'm just curious WHY EXACTLY the thread is being killed in this particular code, given there's no "Response.Redirect", no "Response.End", no pool recycle, no IIS-restart etc etc (typical reasons people are repeating the "background thread in ASP.NET is bad" mantra).

UPDATE: As it turns out it works fine in ASP.NET MVC!!! The thread is aborted in Web-Forms only!! Which is even more weird. Any ideas?

解决方案

Ok, so after 48 hours of experimenting here's what I found:

1. It's fine to run background threads in ASP.NET _MVC_

If you're on MVC - just start your threads as normal, they won't be aborted after the current request ends:

//MVC - works just fine
public ActionResult ThreadTest()
{
    new Thread(delegate() {
        try
        {
            System.Threading.Thread.Sleep(10000);
        }
        catch(Exception ex)
        {
            //no exception will be thrown
        }
    }).Start();
    return Content("ok");
}

2. For Web-Forms - use BackgroundWorker in combination with "Async" page attribute

I learned that with webforms you can't use:

  • new Thread().Start(); //not working

  • ThreadPool.QueueUserWorkItem //not working

  • Action.BeginInvoke //not working

  • A bunch of other things - all not working

Here's what you need to do:

1) Mark your page as "async" in .aspx (this will tell ASP.NET to inherit the page from IAsyncHandler)

<%@ Page language="c#" Async="true" %>

2) Use BackgroundWorker in .aspx.cs

protected void button1_Click(object sender, EventArgs e)
{
    var bg = new BackgroundWorker();
    bg.DoWork += delegate
    {
        try
        {
            Thread.Sleep(10000); //do nothing for 10 seconds
        }
        catch (Exception ex)
        {
            //no excpeiton is thrown
        }

    };
    bg.RunWorkerAsync();
}

3. If you're on .NET 4.5.2 or higher - simply use HostingEnvironment.QueueBackgroundWorkItem

"The HostingEnvironment.QueueBackgroundWorkItem method lets you schedule small background work items. ASP.NET tracks these items and prevents IIS from abruptly terminating the worker process until all background work items have completed. This method can't be called outside an ASP.NET managed app domain."

Kudos to @danny-tuppeny for this last one

这篇关于为什么ASP.NET杀死我的后台线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆