C# - 如何在ASP.NET应用程序中处理子线程

时间:2013-01-09 15:52:39

标签: c# asp.net multithreading

我正在构建一个多线程ASP.NET应用程序。我是编写多线程应用程序的新手。我有一个主类,它产生了许多在使用应用程序时运行的线程。该应用程序有一个主HTML页面。首次打开HTML页面时,它会调用MyController.Start()方法来创建线程并让它们运行。然后HTML页面有一个Javascript例程,它不断轮询我的应用程序中的ASPX页面(每2秒)以获取数据并显示它。有一个名为“MyController”的主类,它是应用程序的核心。它有一个名为Canceled的本地布尔变量,设置为false。 MyController生成所有子线程。每个子线程都有一个循环,只要Canceled = false,就会继续执行。其中一个正在运行的线程用作监视器,以确保HTML页面仍处于运行状态并进行轮询。如果此线程注意到自上次轮询HTML页面以来已过期30秒,则它将Canceled变量更改为true。然后一个接一个地完成所有线程的运行并正常关闭。

我需要能够处理用户关闭浏览器然后在30秒过期之前重新打开它的情况。我不觉得我完全理解创建和启动的线程与MyController实例之间的关系。一旦创建并启动线程,它们只是独立运行吗?我有一个名为App的主静态类,用于从应用程序的任何位置轻松访问控制器。我现在编写代码的方式我认为每次加载HTML页面时都会创建新的线程。因此,如果用户要关闭HTML页面然后重新打开它,我想我会有两个运行的每个线程的实例。那是对的吗?如果是这样,我如何检查这些线程是否已经在运行,以便我不创建它们的新实例?

希望这是有道理的!在此先感谢您的帮助。这是我的代码。

Start.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
  if(App._myController == null)
  {
    App._myController = new MyController();
  }
  App._myController.Start();
}

图书馆代码

public class App
{
  public static MyController _myController {get;set;}
  static App()
  {
    _myController = new MyController();
  }
}

public class MyController
{
  public bool Cancelled {get;set;}
  private object SyncLock = new object();
  Thread _thread1;
  Thread _thread2;
  Thread _thread3;

  public void Start()
  {
    this.Cancelled = false;
    _thread1 = new Thread(Worker1);
    _thread1.Start();

    _thread2 = new Thread(Worker2);
    _thread2.Start();

    _threadMonitor = new Thread(Monitor);
    _threadMonitor.Start();
  }

  public void Stop()
  {
    lock(this.SyncLock)
    {
      this.Cancelled = true;
    }
  }

  private void Worker1()
  {
    while(!Cancelled)
    {
      ..do some stuff..
    }
  }

  private void Worker2()
  {
    while(!Cancelled)
    {
      ..do some stuff..
    }
  }

  private void Monitor()
  {
    while(!Cancelled)
    {
      ..check database to see when last poll was
      ..if last poll is greater than 30 seconds ago
      {
        this.Stop();
      }
    }
  }

}

2 个答案:

答案 0 :(得分:2)

  

我正在构建一个多线程ASP.NET应用程序。我是新来的   编写多线程应用程序。我有一个主类产生一个数字   在使用应用程序时运行的线程。

NOOOO。你不应该这样做。从ASP.NET中生成一个新线程是一种用脚射击自己的公平方法。为什么?因为每个新请求通常从ASP.NET线程池获取专用线程。您可以获得的线程数量非常有限(因此逻辑并发请求的数量)。如果一个请求产生另一个手动线程 - 会发生奇怪的事情,从内存泄漏,死锁开始,最终导致应用程序或Web服务器崩溃。

处理完请求后,您的服务器应该完全忘记用户。

相反,请考虑不同的方法。维持国家:

  • 数据库
  • 用户Cookie
  • Html隐藏字段
  • ASP.NET本身进行序列化/反序列化的ASP.NET容器

恢复每个新请求的状态并比较时间。

答案 1 :(得分:1)

我不喜欢你的设计,但这是一个单独的问题。我将用您当前的设计解决您当前的问题...

Start()函数中,如果线程不为null,则将Cancelled设置为true并将Join()设置为线程,然后继续使用现有功能。

  public void Start()
  {
    this.Cancelled = true;

    if (_thread1 != null) _thread1.Join();
    // repeat for other threads

    this.Cancelled = false;
    _thread1 = new Thread(Worker1);
    _thread1.Start();

    _thread2 = new Thread(Worker2);
    _thread2.Start();

    _threadMonitor = new Thread(Monitor);
    _threadMonitor.Start();
  }

至于更好的方法,可能是一项服务,用于使用WCF(可能使用REST)与您的页面进行交互的后台工作。