У меня есть приложение ASP.NET, которое использует компонент в сборке библиотеки классов для выполнения вызовов веб-службы. Компонент использует пул потоков или какое-либо решение для создания потоков, созданное в домашних условиях, для создания фоновых потоков, в которых выполняются синхронные вызовы веб-службы.
Компонент ведения журнала используется в приложении ASP.NET и вспомогательными классами, которые компонент вызывает из фоновых потоков, порождаемых при вызовах службы.
В ASP.NET HttpModule создает объект контекста ведения журнала и сохраняет его в коллекции HttpContext.Current.Items. Вспомогательные классы, используемые в приложении ASP.NET и во вспомогательных классах, извлекают объект контекста ведения журнала из HttpContext.Current.Items, когда необходимо зарегистрировать сообщение, чтобы украсить зарегистрированное сообщение информацией, которая помещает зарегистрированное сообщение в контекст .
Когда вспомогательные классы вызываются напрямую из ASP.NET, доступен HttpContext.Current.
Когда вспомогательные классы вызываются из фоновых потоков, созданных компонентом, HttpContext.Current имеет значение null, и поэтому для них нет доступного контекста протоколирования при регистрации сообщений; зарегистрированные сообщения бесполезны.
У меня нет контроля над компонентом, который создает потоки для выполнения сервисных вызовов. Если бы я это сделал, я бы организовал копирование и передачу объекта контекста в дочерний поток.
Мой объект контекста ведения журнала не может быть статическим, поскольку он будет перезаписан параллельными потоками запросов ASP.NET, и это будет плохо.
Члены моего объекта контекста протоколирования (простые свойства int / string) могут быть помечены ThreadStatic, что будет работать, и мне больше не нужно будет использовать HttpContext.Current.Items.
Что мне действительно нужно, так это чтобы рабочая среда .NET скопировала объект (или даже передала ссылку; либо сделал бы), и автоматически сделала его доступным для дочерних потоков.
Мне было интересно, смогу ли я добавить элемент в web.config и назначить вспомогательный класс для создания потоков, как вы можете сделать для веб-запросов в% lt; system.net>
Мне также было интересно, могу ли я пометить свой объект контекста ведения журнала каким-либо атрибутом, который вызывает его автоматическое копирование.
Я заглянул в log4nets LogicalThreadContext, попробовал, но это не сработало. Я думаю, что это для передачи информации о контексте регистрации через процессы или границы домена приложения.
Какой механизм LogicalThreadContext log4net использует за кулисами? Что-то из System.Runtime.Remoting? Это устарело сейчас?
Моя среда - .NET 4, поэтому, возможно, с параллельными расширениями или улучшениями для потоков в .NET 4 это теперь возможно.
Кто-нибудь есть идеи, если это вообще возможно? Я начинаю думать нет.
Мне пришлось сделать следующее:
Task<IEnumerable<Account>> accountsTask = Task<IEnumerable<Account>>.Factory.StartNew
(
instrumentationContext =>
{
var parentContext = instrumentationContext as Site.Instrumentation.InstrumentationContext;
if (Site.Instrumentation.InstrumentationContext.Current == null && parentContext != null)
Site.Instrumentation.InstrumentationContext.Current = parentContext;
return GetAccounts();
},
Site.Instrumentation.InstrumentationContext.Current
);
Где метод GetAccounts () вызывает другой класс, который, в свою очередь, зависит от Site.Instrumentation.InstrumentationContext.Current
Проблема в том, что мне НЕ нужно менять код для явной передачи и устанавливать этот объект состояния в дочернем потоке - я хочу, чтобы .NET Framework сделал это для меня автоматически, чтобы код (см. Выше) это создает задачу, которая не мудрее и не должна быть изменена.
Если никто не вносит свой вклад в альтернативы, Джон получает зеленую галочку, поскольку я решил, что это был мой единственный реалистичный выбор, хотя задачи были не потоками.