【问题标题】:What should I be aware of when threading in ASP.NET?在 ASP.NET 中进行线程处理时应该注意什么?
【发布时间】:2009-04-14 01:04:03
【问题描述】:

最近,有关 Winforms 应用程序线程的书(Joe Duffy 在 Windows 上进行并发编程)出版了。这本书专注于 winforms,有 1000 页。

ASP.NET 线程有哪些陷阱?我确信在 ASP.NET 中实现线程时需要注意很多问题。我应该注意什么?

谢谢

【问题讨论】:

    标签: asp.net


    【解决方案1】:

    由于 IIS 接收到的每个 http 请求都是单独处理的,因此无论如何都是在它自己的线程上处理的,所以您应该遇到的唯一问题是,如果您在单个 http 请求的范围内启动了一些长时间运行的进程。在这种情况下,我会将此类代码放入一个单独的引用依赖程序集中,像中间层组件一样编码,完全不依赖或耦合到 ASP.Net 模型,并单独处理该程序集中出现的任何并发问题,无需完全担心 ASP.Net 模型...

    【讨论】:

      【解决方案2】:

      Wintellect 的 Jeff Richter 有一个名为 PowerThreading 的库。如果您在 .NET 上开发应用程序,这将非常有用。 => Power Threading Library

      查看他在各种活动中的在线演示。

      【讨论】:

      • 我支持这个建议。并且一定要加入 Yahoo 群组。
      • 这绝对不能回答这个问题。投反对票。
      【解决方案3】:

      通常鼓励您在 .Net 中使用线程池,因为它有很多好处,代表您管理事物.....但在 ASP.net 中

      由于 ASP.net 已经是多线程的,它使用线程池来处理映射到 ASP.net ISAPI 过滤器的请求,并且由于线程池的大小是固定的,使用它基本上就是在使用线程用于处理请求的工作。

      在小型、低流量的网站中,这不是问题,但在大型、高流量的网站中,您最终会竞争和消耗 ASP.net 进程所依赖的线程。

      如果你想使用线程,可以做类似......

         Thread thread = new Thread(threadStarter);
         thread.IsBackground = true;
         thread.Start(); 
      

      但带有警告:请确保将 IsBackground 设置为 true,因为如果不是,则线程存在于前台,并且可能会阻止 IIS 工作进程回收或重新启动。

      【讨论】:

        【解决方案4】:

        首先,您是在谈论异步 ASP.NET 吗?还是使用 ThreadPool/启动自己的线程?

        如果您不是谈论异步 ASP.NET,那么要回答的主要问题是:您将在其他线程中做什么工作以及该工作是否特定于请求/响应循环,还是更多的是在后台处理全局任务?

        编辑

        如果您需要为给定的请求/响应周期处理并发操作(比多线程 IMO 更好的术语),请使用 ASP 的异步功能。网。这些提供了 IIS 对并发支持的抽象,允许服务器在当前请求等待工作完成时处理其他请求。

        对于全局任务的后台处理,我根本不会使用 ASP.NET。您应该假设 IIS 将在随机时间点回收您的 AppPool。您也不应该假设 IIS 会按任何计划运行您的 AppPool。任何重要的后台处理都应该在 IIS 之外完成,无论是作为计划任务还是作为 Windows 服务。我通常采用的方法是拥有一个 Windows 服务和一个共享的工作队列,网站可以在其中发布工作项。队列可以是数据库表、可靠的基于消息的队列(MSMQ 等)、文件系统上的文件等。

        【讨论】:

        • 我实际上是在谈论两者。这项工作将特定于请求/响应。它还将涉及在后台处理全局、频繁的任务。这里没有实际案例,但这个线程是为了将来的知识。
        【解决方案5】:

        立即想到的是,为什么要在 ASP.NET 中“实现线程”。

        您确实需要始终意识到 ASP.NET 多线程的,因为许多请求可以在各自的线程中同时处理。因此,例如使用静态字段需要考虑线程。

        但是,您很少会想自己在代码中启动一个新线程。

        就 UI 中线程的常见 winforms 问题而言,这些问题在 ASP.NET 中不存在。无需担心基于窗口的消息泵。

        【讨论】:

        • 代码隐藏中的实例变量对于页面的每个实例都是分开的。对同一页面的每个请求都会获得一个新实例,因此,从这个意义上说,它是安全的。产生了多个线程 == “不太安全”
        • @Adam:正如约翰所说,一个实例通常是根据请求创建的,并且仅由一个线程使用。如果您编写原始处理程序 (.ashx),则可以指示一个实例可以被后续请求重用,但它仍然是线程安全的。
        【解决方案6】:

        可以在 ASP.NET 中创建异步页面。这些将执行所有步骤直到某一点。例如,这些步骤将包括异步获取数据。当所有异步任务都完成后,页面生命周期的剩余部分将执行。同时,工作线程没有被占用等待数据库 I/O 完成。

        在此模型中,所有额外线程都在执行,而请求、页面实例和所有控件仍然存在。启动自己的线程时必须小心,在线程执行时,请求、页面实例和控件可能已经被 Disposed。

        此外,像往常一样,请确保多线程实际上会提高性能。通常,额外的线程会使事情变得更糟。

        【讨论】:

          【解决方案7】:

          问题与任何多线程应用程序中的问题几乎相同。

          处理请求所涉及的类(Page、Controls、HttpContext.Current、...)是特定于该请求的,因此不需要任何特殊处理。

          对于您在这些类中作为局部变量或字段实例化的任何类,以及对 Session 的访问,同样如此。

          但是,像往常一样,您需要同步对共享资源的访问,例如:

          • 静态 (C#) / 共享 (VB.NET) 引用。
          • 单身人士
          • 文件系统等外部资源 ...等等...

          我在 ASP.NET 应用程序中经常看到线程错误,例如一个单例被多个并发请求使用而没有同步,导致用户 A 看到用户 B 的数据。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-09-21
            • 2013-01-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-09-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多