Приложение выполняет короткие задачи в потоках 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, Вы писали:
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?
Hello, "Zeiss"
> L>Для чего вам это понадобилось? > Разделяемый между потоками объект, назовём его, например, *команда* может > иметь различные значения в разных потоках.
Для этого замечательно подойдет LogicalCallContex
Posted via RSDN NNTP Server 2.0
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[4]: Как различить потоки, запущенные из ThreadPool?
Здравствуйте, 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 {
// Propertiespublic bool HasInfo { get; }
// Methodspublic 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?
Hello, "Lloyd" > > TK>Для этого замечательно подойдет LogicalCallContex > Он разве написал что использует Remoting?
LogicalCallContex это часть ExecutionContext. То, что доступ осуществляется
через ... CallContext.LogicalSetData/CallContext.LogicalGetData это просто
"особенности" реализации.
Работает это как для пула, так и для "сustom" потоков:
Здравствуйте, Zeiss, Вы писали:
Z>Если да, то мне, чтобы пролучить контекст, на 1.1 придется использовать рефлекшн (internal). Z>Пока не реализовал..
Тады используй просто CallContext.GetData(). Z>Действительно ли, контексты будут различаться при повторном использовании одного и того же потока из ThreadPool'а??
Да.
Re[6]: Как различить потоки, запущенные из ThreadPool?
Hello, "GlebZ"
> Z>Если да, то мне, чтобы пролучить контекст, на 1.1 придется использовать > рефлекшн (internal). > Z>Пока не реализовал.. > Тады используй просто CallContext.GetData().
Там это актуально только для Remoting... между потоками контекст сам не
передается.
Posted via RSDN NNTP Server 2.0
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[7]: Как различить потоки, запущенные из ThreadPool?
Здравствуйте, TK, Вы писали:
TK>Там это актуально только для Remoting... между потоками контекст сам не TK>передается.
Насколько я понял, именно это ему и нужно. Каждому потоку по хранилищу.
Re[7]: Как различить потоки, запущенные из ThreadPool?
Hello, "TK"
> Там это актуально только для Remoting... между потоками контекст сам не > передается.
Хотя, это я соврал Работать будет но, только для потоков из пула. Просто
надо что-бы помещаемые в контекст объекты поддерживали
ILogicalThreadAffinative
Posted via RSDN NNTP Server 2.0
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[7]: Как различить потоки, запущенные из ThreadPool?
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?
GZ>Насколько я понял, именно это ему и нужно. Каждому потоку по хранилищу.
Можно уточнить один момент.
В одной из статей (кажется про DBManager) было сказанно, что [ThreadStatic] атрибут не работает так как надо под asp.net
Можно ли использовать обсуждаемую тут реализацию для хранения каких-то данных уровня потока при работе из под asp.net?
Здравствуйте, valmond, Вы писали:
V>В одной из статей (кажется про DBManager) было сказанно, что [ThreadStatic] атрибут не работает так как надо под asp.net V>Можно ли использовать обсуждаемую тут реализацию для хранения каких-то данных уровня потока при работе из под asp.net?