Как ограничить область видимости именованных слотов LogicalCallContext?
От: LWhisper  
Дата: 01.03.17 11:06
Оценка:
Всем привет.

Возникла проблема при использовании LogicalCallContext в связки с .NET Remoting.
Эта гадость пытается сериализовать данные в именованных слотах и передать на удалённую сторону.
А там далеко не всегда находятся объекты, которые должны и могут сериализоваться.

Одним из варианов решения проблемы является выполнение Remoting-вызовов в отдельном потоке, предварительно огороженным
ExecutionContext.SuppressFlow / RestoreFlow, это мне не подходит.

Другим — очистка LogicalCallContext от именованных данных перед сериализацией сообщения.
Но помимо ремотинга, возникает необходимость ещё и восстановить их обратно после того, как будет получен ответ, в противном случае уже контекст потока будет перезатёрт контекстом с удалённого сервера (тобишь пустым).

Третье решение — жёстко припинить объект в памяти процесса и передать его по ссылке в связке с уникальным хэшем текущего процесса.
Но это не исключает того, что значение может изменяться или использоваться, как на клиенте, так и на сервере, и может просо стать недоступно.

Для организации ремотинга используется кастомный IClientFormatterSink.
Подскажите — как быть в такой ситуации? Пока наиболее правильным кажется второй вариант, но уж очень по походит на танцы на граблях...
c# remoting .net callcontext
Re: Как ограничить область видимости именованных слотов Logi
От: Sinix  
Дата: 01.03.17 11:21
Оценка: 6 (1)
Здравствуйте, LWhisper, Вы писали:

By design, к сожалению.

data
The object to store in the logical call context, this object must be serializable.

(c)
Гугл советует вот этот костыль.
Кстати, а AsyncLocal<T> разве передаётся через ремотинг? Почему бы его не использовать?


UPD И насколько помню, .SuppressFlow() работает и для вызовов ремотинга, т.е. можно оборачивать в него собственно вызовы, без отдельного потока.
Не то чтобы это сильно улучшило код…
Отредактировано 01.03.2017 11:25 Sinix . Предыдущая версия .
Re: Как ограничить область видимости именованных слотов LogicalCallContext?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 01.03.17 11:28
Оценка: +1 :)
Здравствуйте, LWhisper, Вы писали:

LW>Возникла проблема при использовании LogicalCallContext в связки с .NET Remoting.

LW>Эта гадость пытается сериализовать данные в именованных слотах и передать на удалённую сторону.
LW>А там далеко не всегда находятся объекты, которые должны и могут сериализоваться.

Хм.

Only objects that expose the ILogicalThreadAffinative interface and are stored in the CallContext are propagated outside the AppDomain. Objects that do not support this interface are not transmitted in LogicalCallContext instances with remote method calls.

... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[2]: Как ограничить область видимости именованных слотов Logi
От: LWhisper  
Дата: 01.03.17 11:35
Оценка: 24 (1)
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, LWhisper, Вы писали:


S>By design, к сожалению.

S>

S>data
S>The object to store in the logical call context, this object must be serializable.

S>(c)
S>Гугл советует вот этот костыль.
S>Кстати, а AsyncLocal<T> разве передаётся через ремотинг? Почему бы его не использовать?


S>UPD И насколько помню, .SuppressFlow() работает и для вызовов ремотинга, т.е. можно оборачивать в него собственно вызовы, без отдельного потока.

S>Не то чтобы это сильно улучшило код…

Примерно так и делаю. Только там ответ не полный — нужно ещё и восстановить LocalContext перед возвращением ответа.
Этот вариант я описал в п.2

Нет, к сожалению, SuppressFlow не работает для вызовов ремотинга — проверил.

Насчёт AsyncLocal — посмотрю, спасибо!
Re[2]: Как ограничить область видимости именованных слотов LogicalCallContext?
От: LWhisper  
Дата: 01.03.17 11:36
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, LWhisper, Вы писали:


LW>>Возникла проблема при использовании LogicalCallContext в связки с .NET Remoting.

LW>>Эта гадость пытается сериализовать данные в именованных слотах и передать на удалённую сторону.
LW>>А там далеко не всегда находятся объекты, которые должны и могут сериализоваться.

AVK>Хм.

AVK>

AVK>Only objects that expose the ILogicalThreadAffinative interface and are stored in the CallContext are propagated outside the AppDomain. Objects that do not support this interface are not transmitted in LogicalCallContext instances with remote method calls.

Не верь им, обманывают.
Любые объекты. сохранённые в LogicalCallContext пытаются переехать по ремотингу.
Re[2]: Как ограничить область видимости именованных слотов LogicalCallContext?
От: Sinix  
Дата: 01.03.17 11:46
Оценка: 1 (1)
Здравствуйте, AndrewVK, Вы писали:

AVK>Хм.


Позорище, забыл матчасть за ненадобностью.

В общем, интерфейс учитывается только для
// System.Runtime.Remoting.Messaging.CallContext
public static void SetData(string name, object data)
{
    if (data is ILogicalThreadAffinative)
    {
        CallContext.LogicalSetData(name, data);
        return;
    }
    ExecutionContext mutableExecutionContext = Thread.CurrentThread.GetMutableExecutionContext();
    mutableExecutionContext.LogicalCallContext.FreeNamedDataSlot(name);
    mutableExecutionContext.IllogicalCallContext.SetData(name, data);
}


прямой вызов CallContext.LogicalSetData() на ILogicalThreadAffinative не проверяет.
Re[3]: Как ограничить область видимости именованных слотов L
От: Sinix  
Дата: 01.03.17 11:52
Оценка:
Здравствуйте, LWhisper, Вы писали:


LW>Нет, к сожалению, SuppressFlow не работает для вызовов ремотинга — проверил.

Увидел уже
System.Runtime.Remoting.Proxies.RemotingProxy.InternalInvoke() проверь, там видно, что и как прокидывается.

LW>Насчёт AsyncLocal — посмотрю, спасибо!

Должно работать, отпишись по результатам, ок?
Отредактировано 01.03.2017 11:53 Sinix . Предыдущая версия .
Re[4]: Как ограничить область видимости именованных слотов L
От: LWhisper  
Дата: 01.03.17 12:15
Оценка: +1
Здравствуйте, Sinix, Вы писали:

LW>>Насчёт AsyncLocal — посмотрю, спасибо!

S>Должно работать, отпишись по результатам, ок?
Эх, а вот с AsyncLocal не сложилось.
Требует .NET 4.6.2.

Я думаю, будет работать, так как хранит данные не в Datastore LogicalCallContext'а, а в _logicalValues самого ExecutionContext'а и я не вижу, чтобы они пытались куда-то сериализоваться.
Re[5]: Как ограничить область видимости именованных слотов L
От: Sinix  
Дата: 01.03.17 12:20
Оценка:
Здравствуйте, LWhisper, Вы писали:

LW>Эх, а вот с AsyncLocal не сложилось.

LW>Требует .NET 4.6.2.

Вроде бы 4.6, но лучше конечно обновиться, да.

Если проект — не публично доступная библиотека, то что мешает перейти?
Re: Как ограничить область видимости именованных слотов LogicalCallContext?
От: pilgrim_ Россия  
Дата: 02.03.17 18:50
Оценка: 54 (2)
Здравствуйте, LWhisper, Вы писали:

LW>Всем привет.


LW>Возникла проблема при использовании LogicalCallContext в связки с .NET Remoting.

LW>Эта гадость пытается сериализовать данные в именованных слотах и передать на удалённую сторону.
LW>А там далеко не всегда находятся объекты, которые должны и могут сериализоваться.

Как простой вариант — хранить объекты в спец. MBR-враппере, который и будет помещен в call-context:

        private sealed class SuppressSerializationWrapper<TWrapped> : MarshalByRefObject
        {
            public SuppressSerializationWrapper(TWrapped value)
            {
                Value = value;
            }
            public TWrapped Value { get; private set; }
        }
Re[6]: Как ограничить область видимости именованных слотов L
От: LWhisper  
Дата: 03.03.17 11:02
Оценка:
S>Если проект — не публично доступная библиотека, то что мешает перейти?

Слишком большая область поражения. Нужны железобетонные обоснования необходимости перехода на новую версию фреймворка.
Re[2]: Как ограничить область видимости именованных слотов LogicalCallContext?
От: LWhisper  
Дата: 03.03.17 11:03
Оценка:
Здравствуйте, pilgrim_, Вы писали:

_>Здравствуйте, LWhisper, Вы писали:


LW>>Всем привет.


LW>>Возникла проблема при использовании LogicalCallContext в связки с .NET Remoting.

LW>>Эта гадость пытается сериализовать данные в именованных слотах и передать на удалённую сторону.
LW>>А там далеко не всегда находятся объекты, которые должны и могут сериализоваться.

_>Как простой вариант — хранить объекты в спец. MBR-враппере, который и будет помещен в call-context:


_>
_>        private sealed class SuppressSerializationWrapper<TWrapped> : MarshalByRefObject
_>        {
_>            public SuppressSerializationWrapper(TWrapped value)
_>            {
_>                Value = value;
_>            }
_>            public TWrapped Value { get; private set; }
_>        }
_>


Спасибо. Более элегантное решение, чем с IntPtr!
Re[7]: Как ограничить область видимости именованных слотов L
От: Sinix  
Дата: 03.03.17 11:06
Оценка:
Здравствуйте, LWhisper, Вы писали:

S>>Если проект — не публично доступная библиотека, то что мешает перейти?


LW>Слишком большая область поражения. Нужны железобетонные обоснования необходимости перехода на новую версию фреймворка.

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

В общем, с техническим долгом проще не затягивать
Re[8]: Как ограничить область видимости именованных слотов L
От: LWhisper  
Дата: 03.03.17 12:06
Оценка: +1
Здравствуйте, Sinix, Вы писали:

S>Ну, это да. С другой стороны я наблюдал, как этот принцип довели до абсурда. Получили проект на 3.5, который работает на компах 2002 года выпуска и ноль народа, который хочет его поддерживать.

S>В общем, с техническим долгом проще не затягивать

Полностью с тобой согласен.
Если будет достаточно большой промежуток времени на тестирование и насущная необходимость — постараюсь продавить.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.