API CallContext
имеет LogicalGetData
и GetData
, но документация MSDN не очень помогает объяснить разницу между ними и когда они отличаются.
Любые идеи?
API CallContext
имеет LogicalGetData
и GetData
, но документация MSDN не очень помогает объяснить разницу между ними и когда они отличаются.
Любые идеи?
Похоже, что это тонкая разница, связанная с вызовами метода, удаленно выполняемыми в другой AppDomain
. В этом случае создается LogicalCallContext
, и данные хранятся в виде, доступном для LogicalGetData
. В то время как в обычном, не удалённом методе данные хранятся в виде, доступном для GetData
.
При вызове удаленного метода для объекта в другом AppDomain класс CallContext генерирует экземпляр LogicalCallContext, который перемещается вместе с удаленным вызовом. Только объекты, которые открывают интерфейс ILogicalThreadAffinative и хранятся в CallContext, распространяются вне AppDomain в LogicalCallContext. Объекты, которые не поддерживают этот интерфейс, не передаются в экземплярах LogicalCallContext с удаленными вызовами методов.
GetData
:
Извлекает объект с указанным именем из
CallContext
.
LogicalGetData
:
Извлекает объект с указанным именем из контекста логического вызова.
Как правило, данные, хранящиеся через CallContext.SetData
, считаются потоковыми локальными. То есть любой вызов CallContext.GetData
будет получать данные, которые были установлены через SetData из того же потока. Данные, хранящиеся через CallContext.LogicalSetData
, считаются локальными. То есть любые данные, хранящиеся через CallContext.LogicalSetData
, будут "текут" для любых дочерних потоков. Если вы вызываете CallContext.LogicalGetData
в тот же поток или любые дочерние потоки, вы получите данные, которые были сохранены в этом потоке (или родительском потоке), на CallContext.LogicalSetData
.
Как указывает @sixlettervariables, есть также некоторые специфические отличия, связанные с Remoting и перекрестными вызовами AppDomain (возможно, Cross AppDomain подразумевает Remoting, я не знаю, я не знаком с Remoting вообще).
Также, как указано @sixlettervariables, реализуя интерфейс-маркер ILogicalThreadAffinative для объекта, а затем сохраняя этот объект с помощью CallContext.SetData
, объект будет вести себя так, как если бы он был сохранен CallContext.LogicalSetData
.
Вот хорошая публикация блога от Джеффа Рихтера об использовании LogicalSetData/LogicalGetData:
Вот еще несколько ссылок на SO, которые могут пролить свет на CallContext.SetData/GetData, CallContext.LogicalSetData/LogicalGetData и различные формы локального хранилища потоков: