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

CallContext.LogicalGetData Vs. CallContext.GetData

API CallContext имеет LogicalGetData и GetData, но документация MSDN не очень помогает объяснить разницу между ними и когда они отличаются.

Любые идеи?

4b9b3361

Ответ 1

Похоже, что это тонкая разница, связанная с вызовами метода, удаленно выполняемыми в другой AppDomain. В этом случае создается LogicalCallContext, и данные хранятся в виде, доступном для LogicalGetData. В то время как в обычном, не удалённом методе данные хранятся в виде, доступном для GetData.

При вызове удаленного метода для объекта в другом AppDomain класс CallContext генерирует экземпляр LogicalCallContext, который перемещается вместе с удаленным вызовом. Только объекты, которые открывают интерфейс ILogicalThreadAffinative и хранятся в CallContext, распространяются вне AppDomain в LogicalCallContext. Объекты, которые не поддерживают этот интерфейс, не передаются в экземплярах LogicalCallContext с удаленными вызовами методов.

GetData:

Извлекает объект с указанным именем из CallContext.

LogicalGetData:

Извлекает объект с указанным именем из контекста логического вызова.

Ответ 2

Как правило, данные, хранящиеся через 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:

http://www.wintellect.com/CS/blogs/jeffreyr/archive/2010/09/27/logical-call-context-flowing-data-across-threads-appdomains-and-processes.aspx

Вот еще несколько ссылок на SO, которые могут пролить свет на CallContext.SetData/GetData, CallContext.LogicalSetData/LogicalGetData и различные формы локального хранилища потоков:

CallContext vs ThreadStatic

Как передать переменную в другой поток