【问题标题】:When is the Thread Pool created?线程池是什么时候创建的?
【发布时间】:2014-09-26 13:04:05
【问题描述】:

我正在处理我的 WPF 应用程序中的一个问题,该应用程序使用 SQL Anywhere 的 ASP.NET 成员资格和角色提供程序。该应用程序使用 BackgroundWorker 对象在 UI 线程的后台执行任务。简而言之:

  1. 在程序启动期间,应用程序允许用户登录。
  2. 一旦用户登录,它就会创建一个自定义User 类的实例。此类实现IPrincipal 接口。
  3. 创建自定义User 类的实例后,会将其传递给AppDomain.SetThreadPrincipal 方法,以便创建的每个新Thread 都将其用作默认Principal
  4. 后台任务使用Thread.CurrentThread.Principal 属性来确定当前登录用户的名称,并从Role 提供程序检索用户的权限。

这种机制已经运行了 3 年,但最近发生了一些变化。我们已经升级了许多第三方库,现在BackgroundWorker 线程使用默认的Principal,它的用户名是空字符串。这意味着当执行角色检查并且后台任务不工作时,不会从数据库中检索任何数据。

因此,线程池中的线程似乎比最近升级之前的创建时间更快。我想知道它们是什么时候创建的,这样我就可以调查在启动的早期执行用户登录过程的可能性。

.NET 何时创建线程池和其中的线程?

【问题讨论】:

  • .Net 线程池是静态访问,CLR 在进程中加载​​时立即加载(mscoree.dll),一直都是这样,实际上这适用于机器范围内的所有 CLR 实例。在这种情况下,您可能想要调试的问题是 BackgroundWorker 访问 Membership API 以获取用户名时发生的情况,最有可能的问题就在那里。您可能需要添加一些日志记录,以了解访问会员 API 时会发生什么。
  • 线程池是在程序启动时创建的。一些池线程在启动时创建,但其他线程根据需要按需创建。见msdn.microsoft.com/en-us/library/…

标签: c# asp.net wpf multithreading


【解决方案1】:

虽然我无法确切确认线程池何时启动,但我可以确认它可从Application.Startup 事件中获得,这是 WPF 应用程序中引发的第一个事件。这很容易测试.. 在App.xaml 中为该事件添加一个处理程序并从中运行Task

<Application x:Class="Midas.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Startup="App_Startup">
    ...
</Application>

...

public void App_Startup(object sender, StartupEventArgs e)
{
    Task startupTask = new Task(() => SomeMethod());
}

如果对SomeMethod 的调用有效,则线程池正在工作,因为Task 库在后台使用它。来自 MSDN 上的The Managed Thread Pool 页面:

从 .NET Framework 4 开始,使用线程池的最简单方法是使用任务并行库 (TPL)。默认情况下,Task 和 Task 等并行库类型使用线程池线程来运行任务。

【讨论】:

  • 所以看起来线程池在你的程序加载后就可以使用了。没关系。但是它什么时候创建构成它的线程呢?如果 CLR 加载了线程池类,那么为什么相同的代码在最近的升级之前,在 Tread.CurrentPrincipal 属性中具有正确的主体,但在升级之后却没有?跨度>
  • @TonyVitabile 它会根据需要创建它们。如果 ThreadPool 在足够长的时间内充满工作,它会非常缓慢地创建新线程。原始组 (ThreadPool.MinXXXThreads) 是使用线程池本身创建的。
  • @Luaan: 我设法在Thread.SetCurrentPrincipal 方法上放置了一个跟踪点,并发现在程序以`GenericPrincipal' 作为参数启动时确实创建了许多线程我的代码设置了 AppDomain 的线程主体。但是,我不知道该调用是从哪里进行的,因为它是从本机到托管的转换调用的(调用堆栈上唯一的就是对该方法的调用)。我需要在将 AppDomain 的线程主体设置为我的主体时解决此问题;更改初始化顺序可能并不总是有效。
  • @TonyVitabile 或者您可以将 UI 线程的主体传递给后台工作人员;)
  • hmmmmmmm 有趣的想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-03
  • 1970-01-01
  • 1970-01-01
  • 2013-11-24
  • 2016-10-07
  • 2010-11-14
  • 2010-12-04
相关资源
最近更新 更多