【问题标题】:New thread creation silently fails for one controller and not the other? C# ASP.NET (IIS 8.5) Web API 2一个控制器而不是另一个控制器的新线程创建静默失败? C# ASP.NET (IIS 8.5) Web API 2
【发布时间】:2015-12-15 18:19:40
【问题描述】:

我在 Web API 2 项目中设置了两个控制器。第一个控制器通过调用另一个控制器来启动 n 个处理会话。

伪代码中的第一个控制器:

[HttpPost]
public bool Post(...)
{
 ...
 StartProcessingSessions(howMany)
}
void StartProcessingSessions(...)
{
 for (i=1 to HowMany)
  Task.Factory.StartNew(() => StartProcessingSession(...);
}
void StartProcessingSession(...)
{
 [post async to 2nd controller]
}

这段代码运行良好,第二个控制器被调用。第二个控制器尝试以完全相同的方式创建一个线程来执行一些可能长时间运行的工作(1-10 分钟),但该线程无法以静默方式启动。在互联网上搜索后,我阅读了有关在 IIS 中创建线程的支持的相互矛盾的信息。大多数人说4.5.2之后应该没问题,但也有人说它一直有效。由于公司原因,我暂时不能超过 4.5.1。

最重要的是,代码在调试模式下可以正常工作,只有在部署到 Web 服务器时才会失败。

我尝试用简单的数据库日志写入替换处理,但它没有执行。其他创建线程的方法也会静默失败。如果我删除第二个控制器中的线程创建,一切正常。

接下来,我计划尝试对控制器进行简化,看看是否可以查明阻塞线程的确切标准是什么。

有什么见解吗?谢谢

编辑:这是一个简单的控制器,可以作为“控制器 2”来说明问题。第一个日志是写的,第二个不是。

    [HttpPost]
    public bool Post()
    {
        _logRepository.InsertError("Modeling Debugging", "TestController hit");
        Task.Factory.StartNew(() => _logRepository.InsertError("Modeling Debugging", "TestController Thread"));
        return true;
    }

【问题讨论】:

  • 与您的 q 完全无关,但是:您真的需要在您的 Web 应用程序中引入多线程,还是异步编程就足够了?
  • 我需要有效地使 Web 服务器内核饱和以获得最佳吞吐量,这就是第一个控制器将请求拆分为 x 个请求的原因。我不想在处理过程中让控制器调用保持打开状态,因为无论如何都不关心它们的返回值。对我来说似乎更干净。让我知道这对你来说是否有问题。谢谢。
  • 我希望您只用完线程池中的所有线程,结果无法启动更多请求...这是您需要实施的确切模式,以使服务器容易受到少量攻击的传入请求拆分为大量服务器到服务器的请求,从而以非常小的传入流量关闭站点中的所有服务器。
  • 在示例中,我说的只是 1 个请求,因此我们没有接近线程池限制。

标签: c# asp.net multithreading iis iis-8.5


【解决方案1】:

看起来这只是 ASP.NET 的“安全”限制,可能是为了防止开发人员通过请求拆分气球失控而潜在地自爆。我没有找到任何可以证实这一点的信息,但这是我目前唯一合理的解释。

如果您可以使用 .NET 4.5.2+,这可能是一个有争议的问题,因为您拥有的 BackgroundWorker 可能不受此限制。我没有在上面的用例中被阻止,因为尽管我直接将它们作为控制器线程运行,但我仍然能够获得我想要的线程。不是我想要的,但它可以让我充分利用 CPU。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-01
    • 1970-01-01
    • 2016-10-04
    • 2016-04-30
    • 2014-06-06
    • 1970-01-01
    • 2020-07-31
    • 2017-10-14
    相关资源
    最近更新 更多