Механизм блокировки потоков .NET Remoting

У меня неотложная проблема, и я надеюсь, что вы все сможете мне помочь. Я постараюсь объяснить это как можно лучше.

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

Я недавно добавил в эти модули транзакции. Я хотел сделать этот потокобезопасным, если бы клиентский поток A запустил транзакцию базы данных, клиентский поток B не смог бы получить доступ к транзакции клиентского потока A. Тем временем нет необходимости разрешать клиентскому потоку B иметь свою собственную транзакцию, необходимо только, чтобы я не позволял клиентскому потоку B использовать транзакцию клиентского потока A.

Есть только одна ссылка на объект удаленного взаимодействия, который они оба используют, и из-за базовой архитектуры, в которую я не буду входить, я не могу это изменить. Все объекты транзакции хранятся на сервере в этом объекте удаленного взаимодействия.

Я не вижу хорошего способа сделать это, кроме, возможно, передачи информации о клиентском потоке вместе с каждым отдельным вызовом транзакции, что невозможно с моими жесткими временными шкалами. :-( Возможно, если бы объект удаленного взаимодействия мог получить доступ к вызывающему клиентскому потоку, мне бы не пришлось передавать информацию о потоке при каждом вызове, что сделало бы это возможным.

Если бы существовал способ связать клиентский поток с потоком удаленного процесса, я думаю, это помогло бы, но нет документации, которую я мог бы найти по этому поводу.

Надеюсь, я достаточно хорошо это объяснил. Любая помощь приветствуется. Заранее спасибо.


person jnadro52    schedule 22.01.2010    source источник


Ответы (2)


Я не уверен на 100%, можно ли это сделать, но с помощью CallContext может помочь. Вкратце, CallContext - это внеполосные данные, которые можно передавать на сервер удаленно, см. Этот блог здесь в качестве примера. Если вы не понимаете, что такое Out-Of-Band (oob), посмотрите здесь в Википедии. Вот еще один конкретный пример, здесь. Это может дать вам ключ к разгадке.

person t0mm13b    schedule 23.01.2010
comment
Спасибо за это предложение. Я не знал о CallContext, и это могло мне очень помочь. Я просто не знаю, как я могу гарантировать, что информация о потоке всегда будет передаваться. Похоже, мне нужно было бы убедиться, что контекст потока установлен для каждого вызывающего потока, что может быть невозможно с моими временными шкалами. Есть ли какое-то событие, которое запускается перед вызовом удаленного взаимодействия, в котором я мог бы установить контекст вызова для этого потока? Или в контексте вызова по умолчанию сохраняется ссылка на информацию о потоке? Это было бы мне большим подспорьем! Спасибо. - person jnadro52; 26.01.2010
comment
@ jnadro52: я полагаю, непосредственно перед выполнением удаленного вызова установите контекст вызова с идентификатором на стороне клиента, затем на стороне сервера в функции, которая является удаленным вызовом клиента, сначала прочитайте контекст вызова и создайте коллекцию, таким образом вы узнаете, какой клиент использует поток. Единственное, что коллекция должна быть потокобезопасной .... - person t0mm13b; 27.01.2010

То, что вы пытаетесь сделать, звучит немного странно, поэтому позвольте мне посмотреть, понимаю ли я:

  • Вы используете синглтон на стороне сервера, поэтому каждый клиент имеет только 1 поток на сервере.

  • Предполагая, что процесс транзакции занимает много времени (от секунд до минут), другие клиенты ДОЛЖНЫ дождаться завершения первого клиента.

Я думаю, но не уверен, что каждый клиентский вызов создает свой собственный поток. Если это так, то простая реализация некоторых вызовов «блокировки», когда удаленному объекту необходимо выполнять потокобезопасные вызовы, должна помочь. Блокировка стоит дорого, и если транзакция занимает секунды, другой ожидающий может истечь тайм-аут (е-е-е-е-е!)

Именно для этого был создан объект TransactionScope для ( См. MSDN). Я больше не могу помогать, не зная больше об арке решения.

Извините ... Не знаю, полезно это или нет.

person Community    schedule 23.01.2010
comment
Да, это синглтон, я должен был упомянуть об этом ранее. У меня был механизм блокировки потоков с помощью монитора. Я реализовал это на стороне сервера. Это вызывает проблемы, потому что идентификатор потока постоянно меняется на стороне сервера, даже когда тот же клиентский поток вызывает объект удаленного взаимодействия. В этом суть проблемы ... как заблокировать процесс на стороне сервера и гарантировать, что другой клиентский поток не получит доступ к объекту транзакции потока, создавшего объект транзакции? Если бы у меня был способ передать информацию о потоке, это было бы возможно. - person jnadro52; 26.01.2010
comment
@ jnadro52: Мне нравится метод контекста вызова, предложенный tommieb75, как средство определить, является ли он одним и тем же вызывающим абонентом (вроде как состояние сеанса), и использовать потокобезопасную коллекцию из фреймворка. Я предполагаю, что это означает, что вам, возможно, придется передавать объект подключения и использовать его в каждом вызове базы данных, чтобы гарантировать, что вызов выполняется в транзакции. - person ; 29.01.2010