Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

​ThreadStatic - уперся не пойму во что...

226  1 2 все
Murr патриот04.10.17 18:28
Murr
NEW 04.10.17 18:28 

ThreadStatic - уперся не пойму во что...


Написал тестовую многопоточку с шарингом ресурса внутри потока.

Т.е. все, кто работает внутри потока, получают доступ к одному и тому же экземпляру интересующего объекта.

Все класно.


Переношу все на рабочую систему.

Все тоже самое, только вокруг намотано еще много всякого.

Так не работает.

Уже упарился... топовому шаблону отдаю нужный стрингбилдер - он его помещает в треадстатик преременную и использует...

Вопрос - какого хрена второй шаблон не выполняемый в том же потоке не пользует тот же стринг билдер?

А хрен - простой как три рубля - стрингбилдер во втором шаблоне остается нуллом...


А в тестовом варианте все тоже самое, но все - тип-топ... блин... хммм

#1 
Программист коренной житель04.10.17 22:27
04.10.17 22:27 
в ответ Murr 04.10.17 18:28, Последний раз изменено 04.10.17 22:29 (Программист)

Может бать потому что ThreadStatic остается статиком только в пределах одного потока? А в другом потоке имеет другое значение?


A static field marked with T:System.ThreadStaticAttribute is not shared between threads. Each executing thread has a separate instance of the field, and independently sets and gets values for that field. If the field is accessed on a different thread, it will contain a different value.
#2 
Murr патриот04.10.17 23:04
Murr
NEW 04.10.17 23:04 
в ответ Программист 04.10.17 22:27

Ну так это и эксплуатируется - статик в пределах потока - сколько бы объектов не отрабатывало в пределах потока они все должны использовать один и тот же треадстатик объект. Другой поток есть другой поток - там свой объект.


На прототипе все так и работает. Все тоже самое в боевом варианте - не пашет...

#3 
AlexNek патриот04.10.17 23:06
AlexNek
NEW 04.10.17 23:06 
в ответ Murr 04.10.17 18:28
А в тестовом варианте все тоже самое, но все - тип-топ...

отложи проект в сторонку на некоторое время.

Потом сам найдешь ошибку. Что то добавил, изменил, пропустил. Бывает...


ThreadStatic - уперся не пойму во что...

А оно тебе надо? Описание никак не соответствует.

Лучше подобные вещи реализовывать самому.

И обязательно делать "длинный тест". А то часто бывает, полчаса/час работает без проблем, а целый день не выдерживает. В итоге происходят "непонятные" вылеты у заказчика.

#4 
Murr патриот04.10.17 23:28
Murr
NEW 04.10.17 23:28 
в ответ Murr 04.10.17 18:28

Вопрос - какого хрена второй шаблон не выполняемый в том же потоке не пользует тот же стринг билдер?

------

Опечатка. Читать как

Вопрос - какого хрена второй шаблон, выполняемый в том же потоке, не пользует тот же стрингбилдер? Он же один в потоке... так нет - берет с подстраховки нoвый...

#5 
Murr патриот04.10.17 23:35
Murr
NEW 04.10.17 23:35 
в ответ AlexNek 04.10.17 23:06

отложи проект в сторонку на некоторое время.

-----

Так уже... Это третий подход к снаряду...


А оно тебе надо?

------

Мне таки надо - уж больно вкусненько получается на многоядерниках в параллели - с 20 секунд до 0.9 сек...

Ну может быть надо самому объектиком манипулировать... подумаю...

Больше достает, что прототип - пашет, а рабочий вариант не идет...



И обязательно делать "длинный тест".

-----

Мне проще полностью перезапустить процесс.

#6 
AlexNek патриот04.10.17 23:55
AlexNek
NEW 04.10.17 23:55 
в ответ Murr 04.10.17 23:35
Так уже... Это третий подход к снаряду...

тогда ты сделал изменение которое считаешь правильным. Типа вместо интегер пользуем класс. Либо изменение прошло "автоматом" и ты его просто "не видишь".


Мне таки надо - уж больно вкусненько получается на многоядерниках в параллели - с 20 секунд до 0.9 сек...

имелся в виду ThreadStatic.

Как только поток можно реализовать как отдельный класс, данный аттрибут отпадает автоматом.


Мне проще полностью перезапустить процесс.

любишь приехать в воскресенье после обеда? бебе

#7 
Программист коренной житель05.10.17 09:10
NEW 05.10.17 09:10 
в ответ Murr 04.10.17 23:04
Все тоже самое в боевом варианте - не пашет...

Ну значит либо в боевом варианте доступ из другого потока, либо ты где-то обнуляешь созданный стрингбилдер.


Я бы исходил из того, что ThreadStatic работает правильно, а косяк где-то у тебя. Вообще статики - зло, а такие "полустатики" - двойное зло :)

#8 
Murr патриот05.10.17 09:48
Murr
NEW 05.10.17 09:48 
в ответ AlexNek 04.10.17 23:55

Либо изменение прошло "автоматом" и ты его просто "не видишь".

-----

Где-то цто-то Я не вижу. Это понятно.

Непонятно - что именно и где именно Я не вижу.

Проблема - много кода. Что мог - убрал с глаз долой, осталось - почти столько же сколько сколько в прототипе... все одно - не вижу...

Хотя... возможно виртуальность одного из методов мешает... посмотрю.


Как только поток можно реализовать как отдельный класс,

------

В моем случае - поток как метод в классе. Потому - должно работать.

Поменять - можно, но там появится куча проблем с передачей объекта суб-шаблонам.

Потому будет приятно не иметь дела передачей параметров вне начала выполнения метода.



любишь приехать в воскресенье после обеда?

------

Угу... особенно на другой конец шарика...

#9 
Murr патриот05.10.17 09:59
Murr
NEW 05.10.17 09:59 
в ответ Программист 05.10.17 09:10

Ну значит либо в боевом варианте доступ из другого потока,

-----

Другие потоки работают как другие потоки - в них те же самые проблемы.

Создание потоков - контролируется - есть класс Работник, есть класс Менеджер.

Менеджер создает Работников и управляет ими.

В частности - именно Менеджер определяет каким ресурсом будут пользоваться Работники.

Проблем с управлением не наблюдалось.


либо ты где-то обнуляешь созданный стрингбилдер.

------

Обнулять стрингбилдер - вообще плохая идея. Очень дорогой ресурс.

Когда Я тестил время создания и дропа стрингбилдера лет 6-7 назад, то выходило

чуть дольше файлового потока.

Так что стрингбилдеры хранятся в пуле, получаются и возвращаются туда Менеджером.

Во всем коде операции по созданию и обнулению стрингбилдеров есть только в пуле.


а косяк где-то у тебя.

-----

Ну так это понятно. Непонятно как отловить...



Вообще статики - зло

-----

Тебе показать код Оракла? Там статиков ой-ей... и падает при коннекте к 8-ке...

Все еще не доковырял где именно и как чинить...

#10 
Программист коренной житель05.10.17 10:37
NEW 05.10.17 10:37 
в ответ Murr 05.10.17 09:59
Ну так это понятно. Непонятно как отловить...

Ну можно сделать прорети и обеспечить доступ к переменной только через проперти.

Ну а в проперти можно уже добавить отладочную информацию.


Тебе показать код Оракла? Там статиков ой-ей... и падает при коннекте к 8-ке...

Ну и зачем мне код оракла? Темболее в качестве примера говнокода?

#11 
Murr патриот05.10.17 12:16
Murr
NEW 05.10.17 12:16 
в ответ Программист 05.10.17 10:37

Ну а в проперти можно уже добавить отладочную информацию.

------

Так и сделано. Там встроен аварийный подстановщик стрингбилдера.

Только проблема была именно в том, что он использовался.


Ладушки - нашел Я откуда пришла проблемка.

Дело было так: - мелкомягкие для упрощения компиляции шаблона предоставляют базовый класс с кучей функциональности.

Поменять то, что генерируется при компиляции шаблона Я "не могу". Остается - использовать функциональность того что предлагает мелкософт.

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


Потому делается простая генерация, из сгенерированного соурсника вырезается сгенерированный базовый класс, класс модифицируется "как надо" под задачу и подставляется в качестве базового в кучу шаблонов.


Я все сделал и на этом прокололся.

Дело в том, что в базовом классе поле под стрингбилдер есть нормальное, не статическое, поле.

Повесив на него треадстатик атрибут Я ничего не поменял.

Надо было еще и поле сделать статическим. Только тогда аттрибут переведет его в один-на-поток вариант...

Все - эта часть - работает.


Теперь надо придумать как вызывать обработчик "генерация суб-шаблоном завершена" - бо, суб-шаблоны могут быть файлогенерирующими...


Но это - не сегодня - сегодня надо починить оракловский коннект с 12-го клиента на 8-ю базу...


Ну и зачем мне код оракла?

------

А чтобы ты не кричал что статики это всегда плохо.

Могли они слепить синглетоны, но оставили статики. Ну да и фиг с ним - если бы работало - было бы даже не интересно как сделано.

А падает он не на этих статиках...

#12 
AlexNek патриот05.10.17 23:13
AlexNek
NEW 05.10.17 23:13 
в ответ Murr 05.10.17 09:48

вот как имелось в виду

public class TestInteraction : ExecutionAsync
{
  private Xxx _myThreadInstance = new Xxx();

  protected override void DoWork(object sender, DoWorkEventArgs e)
  {
     while (!CancellationPending)
     {
        //код для выполнения в потоке...
     }
  }
}

Для такого ThreadStatic совсем не нужен. Хотя похоже ты там опять что то накрутил.

#13 
Murr патриот05.10.17 23:39
Murr
NEW 05.10.17 23:39 
в ответ AlexNek 05.10.17 23:13

Это понятно.

Мне нужно, чтобы Ххх создавался вне потока и управлялся вне потока.

Бо, накладно создавать стрингбилдеры. Потому они хранятся в пуле, получаются Менеджером и им же возвращаются.


Как сейчас работает - меня устраивает.


Теперь надо думать как организовать запись результатов генерации.

Т.е. надо определять категорию шаблона - файло-генерирующий или тексто-генерирующий и писать нужное.


Вот чего пока еще не продумал до конца - какое поведение задавать. И хочется его менять... в том числе - на лету...

Ну да это не завтра.

Завтра мне Оракла мучать - надо выяснить что не так с ответом 8-ки... в 12-м клиенте.

#14 
AlexNek патриот05.10.17 23:49
AlexNek
NEW 05.10.17 23:49 
в ответ Murr 05.10.17 23:39
Мне нужно, чтобы Ххх создавался вне потока
public class TestInteraction : ExecutionAsync
{
  private Xxx _myThreadInstance;
  public TestInteraction(Xxx myThreadInstance)
  {
    _myThreadInstance = myThreadInstance;
  }

  protected override void DoWork(object sender, DoWorkEventArgs e)
  {
     while (!CancellationPending)
     {
        //код для выполнения в потоке...
     }
  }
}
#15 
Murr_0002 знакомое лицо06.10.17 11:10
Murr_0002
NEW 06.10.17 11:10 
в ответ AlexNek 05.10.17 23:49

Извини, не точно выразился.


См. аттачмент.


Там не полная картинка, но основную проблему она показывает.


В полной - шаблоны и другие ресурсы создаются вне потока .

Поток лишь выполняет работу используя предоставленные ресурсы.

В принципе, поток не знает что именно за ресурсы ему даны - СтрингБилдер вполне можно заменить фаиловым или сетевым потоком.


#16 
AlexNek патриот06.10.17 23:31
AlexNek
NEW 06.10.17 23:31 
в ответ Murr_0002 06.10.17 11:10

тут видно сразу несколько проблем:

-поток не может быть закончен когда потребуется

-паралельные потоки не должны быть зависимы один от другого

protected override void DoWork(object sender, DoWorkEventArgs e)
        {
            // none of params can be passed - only default constructor available
            T1 t1 = new T1();
            // this is the only point where assigment can be done
            t1.GenerationEnvironment = _myThreadInstance;
            // generate output by T1 & T2 (as it called in T1)
            string text = t1.TransformText();
            // in real world, unfortunetly, I need an option to write generated 
            // text to file after T2 generation complete, but before T1 will finish 
            // his work.
        }

А что мешает сделать TestInteractionT1 и TestInteractionT2 + синхронизация?

Хотя синхронизация будет чисто по времени записи.


ManualResetEvent sync = new ManualResetEvent(false);

StringBuilder myThreadInstance = ...

T1 t1 = new T1();

t1.GenerationEnvironment = myThreadInstance;

t1Thread = new TestInteractionT1(t1,myThreadInstance,sync);


T2 t2 = new T2();

t2.GenerationEnvironment = myThreadInstance;

t2Thread = new TestInteractionT2(t2,myThreadInstance,sync);

t1Thread.Start();

t2Thread.Start();

#17 
Murr_0002 знакомое лицо07.10.17 10:08
Murr_0002
NEW 07.10.17 10:08 
в ответ AlexNek 06.10.17 23:31

-паралельные потоки не должны быть зависимы один от другого

-----

Они и не зависимы.

Тебе даны всего два шаблончика для примера. В тестовой схеме, которая эмулирует возможные ситуации, их 12-ть.

В рабочей системе их у меня сейчас около 200-т... из них уровня Т1 - 2-3 десятка.

Вот для этих 2-3 десятков и делаются отдельные потоки.


-поток не может быть закончен когда потребуется

------

А поток в любом случае не может быть нормально завершен до окончания вызова т1.ТрансформТехт()

- у шаблона нет возможности терминировать выполнение метода.

А по окончании вызова - заканчивается и поток.

У менеджера - по другому - там есть возможность сделать Канцел.

С управлением можно играться довольно долго и все будет работать - проблема не в нем.


+ синхронизация?

-----

Считай так:

т1 - пишет заголовок класса и имена методов.

т2...т1000 - пишут тела методов.

кроме этих двух уровней есть еще нелимитированное вложение и рекурсивные вызовы

- типа, один из шаблонов пишет цикл, другой - иф.

Как предлагается сделать синхронизацию после окончания генерации? По времени?

Так там - параллельные потоки - нет никаких гарантий по времени...



t2Thread = new TestInteractionT2(t2,myThreadInstance,sync);

-----

Вынеси Т1 и Т2...Т1000 в отдельную ДЛЛку и работай с ней как с блакбоксом.

Базовый класс - еще в отдельную ДЛЛку.

В дополнение - Т1 - паблик, вызываемые - интернал.

В результате упрешься в задачку https://foren.germany.ru/programmer/f/32477296.html?Cat=&p...

#18 
AlexNek патриот07.10.17 16:05
AlexNek
NEW 07.10.17 16:05 
в ответ Murr_0002 07.10.17 10:08
Они и не зависимы.


т1 - пишет заголовок класса и имена методов.т2...т1000 - пишут тела методов.

что то тут противоречия в одном ответе.

Зависимости разруливаются другими методами. Не сливай всё в один котел.


#19 
Murr_0002 знакомое лицо07.10.17 17:49
Murr_0002
NEW 07.10.17 17:49 
в ответ AlexNek 07.10.17 16:05

что то тут противоречия в одном ответе.

-----

Нету там противоречия. Ибо написано:

Вот для этих 2-3 десятков и делаются отдельные потоки.


Зависимости разруливаются другими методами.

-----

Ну предложи удобную систему - Я долго подбирал что мне надо. Тот компромисс что получается вроде годится.


Не сливай всё в один котел.

-----

??? - чтобы Я делал по другому - нужно предложить лучшее решение.

Запустить каждый шаблон и суб-шаблон в своем потоке - не проблема.

Проблемой будет последующая сборка результатов... и мне ею заниматься не хочется, бо, других проблем хватает.

Так что есть шаблоны которыми может оперировать Менеджер - их и достаточно.

Чего и сколько еще есть в библиотеке шаблонов - мне и знать не хочется. Об том прогер подумал.

Тем более, что один и тот же результат можно получить бесконечным количеством способов.

#20 
1 2 все