Подтвердить что ты не робот

В чем разница между log4net.ThreadContext и log4net.LogicalThreadContext?

ОБНОВЛЕНО 11/18/2014 - При просмотре репозитория журналов log4net я обнаружил, что реализация LogicalThreadContext была изменена в ноябре 2011 года на то, что он сохраняет свои свойства с помощью CallContext.LogicalSetData(и получает их с помощью LogicalGetData). Это важно, потому что это означает, что LogicalThreadContext теперь должен работать правильно. Любые данные, хранящиеся в LogicalThreadContext, должны "течь" на любые дочерние потоки или задачи. Это сравнивается с ThreadContext (и старой реализацией LogicalThreadContext), где данные, хранящиеся в контексте, останутся локальными для текущего потока и НЕ будут переданы дочерним потокам/задачам.

Если вам интересно, вот изменение:

http://svn.apache.org/viewvc/logging/log4net/trunk/src/log4net/Util/LogicalThreadContextProperties.cs?r1=1165341&r2=1207948&diff_format=h

Надеюсь, что кто-то, кто сталкивается с этим старым вопросом, найдет эту информацию полезной.

log4net предоставляет два разных объекта контекста потока: ThreadContext и LogicalThreadContext, каждый из которых имеет свойство bag, Properties. ThreadContext имеет ThreadContextProperties мешок, в то время как LogicalThreadContext имеет LogicalThreadContextProperties.

ThreadContext, возможно, более известен как "MDC" . LogicalContext, возможно, более известен как "LDC". Я буду использовать короткое имя для остальной части этого сообщения.

MDC.Properties реализуется с помощью System.Threading.Thread.SetData, тогда как LDC.Properties реализуется с использованием System.Runtime.Remoting.Messaging.CallContext.SetData.

Для сравнения, NLog предоставляет только "MDC" (теперь известный как MappedDiagnosticContext) для хранения локальных свойств потока. Реализация NLog использует System.Threading.Thread.SetData, поэтому его реализация такая же, как и log4net.

В log4net и NLog свойства "MDC" хранятся в словаре, который сам хранится в локальном хранилище потоков.

В таком случае сохранение словаря в переменной члена класса, украшенной [ThreadStatic], эквивалентно?

[ThreadStatic]
private static IDictionary<string, string> threadProperties;

Каким будет эквивалентное (или подобное) объявление с использованием .NET 4.0 нового класса ThreadLocal?

В конечном счете, какова реальная, практическая разница между НРС и МДК? Даже после прочтения тем MSDN, приведенных выше, мне это непонятно. Когда вы действительно будете использовать один над другим? Похоже, что подавляющее большинство ссылок/примеров, которые я вижу для log4net и контекста, для GDC (глобальный - я понимаю), NDC (вложенный, что я также понимаю), и MDC. Большинство ссылок, которые я могу найти в LDC (или LogicalThreadContext), когда googling связаны с проверками в репозиториях исходного кода log4net, а не в реальном мире. НРС почти никогда не возникает в вопросах или примерах.

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

Чем больше вопрос, не связанный напрямую с log4net, какова практическая разница между Thread.SetData и CallContext.SetData?

Согласно статье CallContext MSDN данные CallContext могут быть переданы другому AppDomain. Чтобы размножаться, элемент данных, хранящийся в CallContext, должен выставлять ILogicalThreadAffinative интерфейс. Таким образом, это, по-видимому, одно отличие между Thread.SetData и CallContext.

Согласно ссылке Nicko Cadell, log4net не реализует ILogicalThreadAffinative, поэтому свойства LDC не будут распространяться.

Может быть, здесь достаточно, чтобы я мог ответить на свой вопрос, может быть, и нет. Я все еще работаю над пониманием.

Если вы используете log4net, вы используете MDC, LDC, оба? Если вы используете MDC, это потому, что большинство примеров "реального мира", похоже, используют его? Если вы используете LDC, у вас есть конкретная причина для его использования? Если вы используете оба варианта, как вы выбираете, когда их использовать?

Обратите внимание, что некоторые статьи о MDC (и, возможно, LDC), возможно, не работают в приложениях ASP.net из-за переключения потоков. Меня это не особенно интересует, поскольку я не работаю в ASP.net.

Собственно, я нашел здесь несколько полезных сообщений о SO, которые могут способствовать обсуждению:

Каковы наилучшие методы для использования локального хранилища потоков в .NET?

.Net: логическая нить и локальное хранилище потоков?

Спасибо заранее!

4b9b3361

Ответ 1

Предупреждение: это догадки.

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

Это означает, что работа, соответствующая одному запросу, разбросана среди множества разных потоков (обработка асинхронных запросов веб-службы). Я подозреваю, что CallContext используется для распространения "всего, что я делаю, из-за этого входящего запроса" на разные потоки, чтобы вы могли собрать все журналы для этого запроса вместе. ThreadContext не поможет. Обратите внимание, что я предполагаю, что вся работа выполняется в одном приложении AppDomain, поэтому ваша проблема не будет проблемой.