2014-09-26 7 views
1

Я работаю над проблемой в своем приложении WPF, которое использует членство ASP.NET & Поставщики ролей для SQL Anywhere. Приложение использует объекты BackgroundWorker для выполнения задач в фоновом режиме от потока пользовательского интерфейса. В двух словах:Когда создается пул потоков?

  1. При запуске программы, приложение позволяет пользователю войти в систему
  2. После того, как пользователь вошел в систему, он создает экземпляр пользовательского класса User.. Этот класс реализует интерфейс IPrincipal.
  3. После создания экземпляра настраиваемого класса User он передается методу AppDomain.SetThreadPrincipal, так что каждый созданный новый Thread использует его как значение по умолчанию Principal.
  4. В фоновых задачах используется свойство Thread.CurrentThread.Principal, чтобы определить имя пользователя, который в настоящее время вошел в систему, и получить разрешения пользователя от поставщика Role.

Этот механизм отлично работает в течение 3 лет, но в последнее время что-то изменилось. Мы обновили ряд сторонних библиотек, и теперь потоки BackgroundWorker используют по умолчанию Principal, который имеет пустую строку в качестве имени пользователя. Это означает, что данные не извлекаются из базы данных при выполнении проверок ролей и фоновых задач не работают.

Похоже, что потоки в пуле потоков создаются раньше, чем раньше, до недавних обновлений. Я хотел бы узнать, когда они создаются, поэтому я могу исследовать возможность выполнения процесса входа пользователя в систему в начале процесса.

Только когда .NET создает пул потоков и потоки внутри него?

+0

.Net-пул потоков является статическим доступом, загружает, как только CLR загружается в процессе (mscoree.dll), он всегда был таким, на самом деле это для всех экземпляров CLR. В этом случае проблема, которую вы можете отлаживать, - это то, что происходит, когда BackgroundWorker обращается к API-интерфейсам Membership для получения имени пользователя, скорее всего, проблема будет там. Возможно, вы захотите добавить некоторые протоколирования, чтобы выяснить, что происходит при доступе к API членства. –

+0

Пул потоков создается при запуске программы. При запуске создаются несколько потоков потоков, но при необходимости создаются другие по требованию. См. Http://msdn.microsoft.com/en-us/library/system.threading.threadpool (v = vs.110) .aspx –

ответ

0

Хотя я не могу точно подтвердить, когда запущен пул потоков, я могу подтвердить, что он доступен из события 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 использует ее под обложками. С The Managed Thread Pool страницы на MSDN:

Начиная с .NET Framework 4, самым простым способом, чтобы использовать пул потоков является использование библиотеки Task Parallel Library (TPL). По умолчанию параллельные библиотеки, такие как Task и Task, используют потоки пула потоков для запуска задач.

+0

Итак, кажется, что пул потоков доступен для использования, как только ваша программа загружается. Хорошо. Но когда он создает потоки, которые его составляют? Если его, как только класс пула потоков загружается CLR, то почему он должен иметь тот же самый код перед последними обновлениями в правиле принципала 'Tread.CurrentPrincipal', но не после обновления? –

+0

@TonyVitabile Он создает их по мере необходимости. Если ThreadPool полон работы в течение достаточно долгого времени, он будет создавать новые потоки очень медленно. Исходный пучок ('ThreadPool.MinXXXThreads') создается с помощью самого пула потоков. – Luaan

+0

@ Luaan: Мне удалось установить точку трассировки в методе Thread.SetCurrentPrincipal и обнаружил, что действительно существует ряд потоков, которые создаются, когда программа начинается с «GenericPrincipal» в качестве параметра до того, как мой код устанавливает AppDomain Директор темы. Однако я не могу сказать, откуда этот вызов, поскольку он вызывается из перехода с управляемым к управляемому (единственное, что в стеке вызовов - это вызов этого метода). Мне нужно взглянуть на исправление этого в то время, когда Принцип Thread для AppDomain задан для моего принципала; изменение порядка инициализации может не всегда работать. –

Смежные вопросы