Как различить потоки, запущенные из ThreadPool?
От: Zeiss  
Дата: 27.01.06 15:11
Оценка:
Приложение выполняет короткие задачи в потоках ThreadPool'а.
Как организовать TLS * для этих потоков?

Проблема: ThreadPool повторно использует (recycles) потоки, т.е. запускает для новых задач потоки, которые, возможно, ранее уже выполняли аналогичную работу. Таким образом, получить уникальный ключ для потока нельзя, и стандартный код типа
TLS tls = (TLS) hashtable[Thread.CurrentThread];
if (tls == null) { /* это новый поток, создаем для него свой TLS */  }
работает неправильно, если текущий поток уже был использован.

Таким образом, необходимо не только дифференцировать потоки в отдельно взятый момент времени, но и на протяжении работы процесса.

Свойство System.Thread.Name не годится, т.к. оно set-once.
Использование LocalDataStoreSlot тоже не подходит, т.к. слоты при перезапуске потоков из ThreadPool'а не сбрасываются.
Thread.GetHashCode(), AppDomain.GetCurrentThreadId() и одноименная функция из Kernel32.dll также возвращают повторяющиеся значения.

* Thread Local Storage. Необходимо ассоциировать с текущим потоком значение, не повторяющееся между потоками.
Re: Как различить потоки, запущенные из ThreadPool?
От: Chardex Россия  
Дата: 27.01.06 15:15
Оценка:
Здравствуйте, Zeiss, Вы писали:

Z>* Thread Local Storage. Необходимо ассоциировать с текущим потоком значение, не повторяющееся между потоками.


А свойство Name не подходит?
Re[2]: Как различить потоки, запущенные из ThreadPool?
От: Zeiss  
Дата: 27.01.06 15:38
Оценка:
Здравствуйте, Chardex, Вы писали:

C>А свойство Name не подходит?


Читайте, пожалуйста, внимательно:

Свойство System.Thread.Name не годится, т.к. оно set-once

Его можно установить только единожды.
Во-вторых, это свойство может установить код, к которому я не имею отношения.
Спасибо
Re[2]: Как различить потоки, запущенные из ThreadPool?
От: Максим Зелинский  
Дата: 27.01.06 15:39
Оценка:
Здравствуйте, Chardex, Вы писали:

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


Z>>* Thread Local Storage. Необходимо ассоциировать с текущим потоком значение, не повторяющееся между потоками.


C>А свойство Name не подходит?

Было отмечено, что Name — Set once (точнее Write once). Вот код для еденички:
public void set_Name(string value)
{
      lock (this)
      {
            if (this.m_Name != null)
            {
                  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WriteOnce"));
            }
            this.m_Name = value;
            if (Debugger.IsAttached)
            {
                  Thread.InformThreadNameChange(this);
            }
      }
}
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re: Как различить потоки, запущенные из ThreadPool?
От: Lloyd Россия  
Дата: 27.01.06 16:04
Оценка:
Здравствуйте, Zeiss, Вы писали:

Z>Приложение выполняет короткие задачи в потоках ThreadPool'а.

Z>Как организовать TLS * для этих потоков?

Для чего вам это понадобилось?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Как различить потоки, запущенные из ThreadPool?
От: TK Лес кывт.рф
Дата: 27.01.06 16:30
Оценка:
Hello, "Zeiss"
> Приложение выполняет короткие задачи в потоках ThreadPool'а.
> Как организовать TLS * для этих потоков?
>

Очень на то похоже, что использовать надо LogicalCallContext.
Posted via RSDN NNTP Server 2.0
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[2]: Как различить потоки, запущенные из ThreadPool?
От: Zeiss  
Дата: 27.01.06 16:44
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Для чего вам это понадобилось?


Разделяемый между потоками объект, назовём его, например, *команда* может иметь различные значения в разных потоках.
Re[3]: Как различить потоки, запущенные из ThreadPool?
От: TK Лес кывт.рф
Дата: 27.01.06 16:46
Оценка: 14 (2)
Hello, "Zeiss"

> L>Для чего вам это понадобилось?

> Разделяемый между потоками объект, назовём его, например, *команда* может
> иметь различные значения в разных потоках.

Для этого замечательно подойдет LogicalCallContex
Posted via RSDN NNTP Server 2.0
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[4]: Как различить потоки, запущенные из ThreadPool?
От: Lloyd Россия  
Дата: 27.01.06 17:04
Оценка:
Здравствуйте, TK, Вы писали:

TK>Для этого замечательно подойдет LogicalCallContex


Он разве написал что использует Remoting?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Как различить потоки, запущенные из ThreadPool?
От: Zeiss  
Дата: 27.01.06 17:19
Оценка:
Здравствуйте, TK, Вы писали:

TK>Hello, "Zeiss"


>> L>Для чего вам это понадобилось?

>> Разделяемый между потоками объект, назовём его, например, *команда* может
>> иметь различные значения в разных потоках.

TK>Для этого замечательно подойдет LogicalCallContex


вот это?


namespace System.Threading {
    public sealed class Thread {
        internal LogicalCallContext GetLogicalCallContext();
        /* ... */
    }
}

namespace System.Runtime.Remoting.Messaging {
    public sealed class LogicalCallContext : ISerializable, ICloneable {
        // Properties
        public bool HasInfo { get; }

        // Methods
        public object Clone();
        public void FreeNamedDataSlot(string name);
        public object GetData(string name);
        public void GetObjectData(SerializationInfo info, StreamingContext context);
        public void SetData(string name, object data);
    }
}


Если да, то мне, чтобы пролучить контекст, на 1.1 придется использовать рефлекшн (internal).

Пока не реализовал..
Действительно ли, контексты будут различаться при повторном использовании одного и того же потока из ThreadPool'а??
Спасибо
Re[5]: Как различить потоки, запущенные из ThreadPool?
От: TK Лес кывт.рф
Дата: 27.01.06 17:19
Оценка:
Hello, "Lloyd"
>
> TK>Для этого замечательно подойдет LogicalCallContex
> Он разве написал что использует Remoting?

LogicalCallContex это часть ExecutionContext. То, что доступ осуществляется
через ... CallContext.LogicalSetData/CallContext.LogicalGetData это просто
"особенности" реализации.

Работает это как для пула, так и для "сustom" потоков:

static void Main(string[] args)
{
   CallContext.LogicalSetData("someString", DateTime.Now);
   ThreadStart action = delegate() { Console.WriteLine("Ctx:{0}", 
CallContext.LogicalGetData("someString")); };
   action.BeginInvoke(null, null);
   Thread trd = new Thread(delegate() { 
Console.WriteLine("Ctx:{0}",CallContext.LogicalGetData("someString")); });
   trd.Start();
   Console.ReadLine();
}
Posted via RSDN NNTP Server 2.0
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[5]: Как различить потоки, запущенные из ThreadPool?
От: TK Лес кывт.рф
Дата: 27.01.06 17:36
Оценка:
Hello, "Zeiss"
>
> Если да, то мне, чтобы пролучить контекст, на 1.1 придется использовать
> рефлекшн (internal).
>

Тут все еще проще — в 1.1 передачи контекста между потоками не произойдет.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[5]: Как различить потоки, запущенные из ThreadPool?
От: GlebZ Россия  
Дата: 27.01.06 17:43
Оценка:
Здравствуйте, Zeiss, Вы писали:

Z>Если да, то мне, чтобы пролучить контекст, на 1.1 придется использовать рефлекшн (internal).

Z>Пока не реализовал..
Тады используй просто CallContext.GetData().
Z>Действительно ли, контексты будут различаться при повторном использовании одного и того же потока из ThreadPool'а??
Да.
Re[6]: Как различить потоки, запущенные из ThreadPool?
От: GlebZ Россия  
Дата: 27.01.06 17:45
Оценка:
Здравствуйте, TK, Вы писали:

Слушай. Ты умный. Можешь мне объяснить разницу между LogicalCallContext и CallContext. Не могу врубиться. А я тебе оценочку потавлю.
Re[6]: Как различить потоки, запущенные из ThreadPool?
От: TK Лес кывт.рф
Дата: 27.01.06 17:47
Оценка:
Hello, "GlebZ"

> Z>Если да, то мне, чтобы пролучить контекст, на 1.1 придется использовать

> рефлекшн (internal).
> Z>Пока не реализовал..
> Тады используй просто CallContext.GetData().

Там это актуально только для Remoting... между потоками контекст сам не
передается.
Posted via RSDN NNTP Server 2.0
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[7]: Как различить потоки, запущенные из ThreadPool?
От: GlebZ Россия  
Дата: 27.01.06 17:52
Оценка:
Здравствуйте, TK, Вы писали:

TK>Там это актуально только для Remoting... между потоками контекст сам не

TK>передается.
Насколько я понял, именно это ему и нужно. Каждому потоку по хранилищу.
Re[7]: Как различить потоки, запущенные из ThreadPool?
От: TK Лес кывт.рф
Дата: 27.01.06 18:05
Оценка: 2 (1)
Hello, "TK"

> Там это актуально только для Remoting... между потоками контекст сам не

> передается.

Хотя, это я соврал Работать будет но, только для потоков из пула. Просто
надо что-бы помещаемые в контекст объекты поддерживали
ILogicalThreadAffinative
Posted via RSDN NNTP Server 2.0
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[7]: Как различить потоки, запущенные из ThreadPool?
От: TK Лес кывт.рф
Дата: 28.01.06 01:10
Оценка: 105 (9)
Hello, "GlebZ"

> Можешь мне объяснить разницу между LogicalCallContext и CallContext.


LogicalCallContext это фактически data holder для данных передаваемых вместе с "логическим" потоком. Фактически, логический поток это тот поток, что рисуется на sequence диаграмме. У каждого потока, есть свой экземпляр LogicalCallContex (кроме логического у потока есть нелогический IllogicalCallContext который остается всегда с потоком и никуда не передается). Фактически, все контексты храняться как часть общего класса ExecutionContext. Так вот, CallContext это фактичски враппер (реализован как static класс) над экземплярами LogicalCallContext и IllogicalCallContext. При этом, LogicalCallContext иммеет более высокий приоритет (т.е. если значение есть в логическом контексте то, вернут его. если в нем такого значения нет то, для поиска будет использован "нелогический"). Так же, у LogicalCallContext есть ограничение на возможные типы данных — классы должны наследоваться от ILogicalThreadAffinative. Если значение передаваемое в CallContext.SetData поддерживает этот интерфейс то, оно будет сохранено в логическом контексте. В противном случае в "нелогическом" (в .net 2.0 требование с интерфейсом можно обойти — там для логического контекста есть спец. методы LogicalSetData/LogicalGetData в этом случае, можно использовать практически любой объект).
Posted via RSDN NNTP Server 2.0
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[8]: Как различить потоки, запущенные из ThreadPool?
От: valmond Россия http://blogs.technet.com/valmond/
Дата: 28.01.06 06:07
Оценка:
GZ>Насколько я понял, именно это ему и нужно. Каждому потоку по хранилищу.

Можно уточнить один момент.
В одной из статей (кажется про DBManager) было сказанно, что [ThreadStatic] атрибут не работает так как надо под asp.net
Можно ли использовать обсуждаемую тут реализацию для хранения каких-то данных уровня потока при работе из под asp.net?
Заметки — SharePoint & InfoPath
http://blogs.technet.com/valmond/
Re[9]: Как различить потоки, запущенные из ThreadPool?
От: Zeiss  
Дата: 29.01.06 16:37
Оценка:
Здравствуйте, valmond, Вы писали:

V>В одной из статей (кажется про DBManager) было сказанно, что [ThreadStatic] атрибут не работает так как надо под asp.net

V>Можно ли использовать обсуждаемую тут реализацию для хранения каких-то данных уровня потока при работе из под asp.net?

То немножко другое.
Думаю, можно.
См. здесь
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.