|
Странное поведение потока
|
|||
---|---|---|---|
#18+
Какая-то непонятная ерунда творится. Есть небольшое WPF приложение. В нем создан поток со следующим кодом (см. ниже). В коде всю полезную работу закомментировал, но задержка на точке останова большая. Причем, иногда я запускаю приложения и все летает (то есть каждую секунду попадаем на строчку future_dt = cur_dt.AddSeconds(1)), а иногда какая-то засада случается на Thread.Sleep. Запускаю непосредственно из VS 2010. Я не специалист в C#, поэтому не понимаю с чем это может быть связано. Думал, может GC включается в работу, но даже перегружал комп - не помогло. Посидел, попил чаек, через час подхожу - все летает. На следующий день - опять тормоза Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26.
... |
|||
:
Нравится:
Не нравится:
|
|||
15.05.2015, 22:01 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
Перед тем как начал писать, были торомоза. Запустил спустя 5 минут все летает. Подозреваю, что GC это. Как бороться?! ... |
|||
:
Нравится:
Не нравится:
|
|||
15.05.2015, 22:05 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
если есть Task'и нафига использовать Thread? ... |
|||
:
Нравится:
Не нравится:
|
|||
15.05.2015, 23:56 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
myaucha Код: c# 1.
Минимальный интервал времени для данного метода не менее 10 миллисекунд. Обычно - 15 мс. Реально - больше. К тому же, это лишь намёк потоку, что пора бы проснуться, а если у ОС есть другие дела, то поток может спать ещё долго. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 01:15 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
petalvikМинимальный интервал времени для данного метода не менее 10 миллисекунд. Обычно - 15 мс. Реально - больше. К тому же, это лишь намёк потоку, что пора бы проснуться, а если у ОС есть другие дела, то поток может спать ещё долго.Если минимальный интервал 10-15 мс, то каким образом приведенный код работает иногда без задержек (как положено - какжую секунду), а иногда сильно подвисает (жду по 30 секунд). Ведь если бы интервал был 10-15 мс, то подвисание было бы постоянным. В период подвисания я смотрел диспетчер задач - активность снижается практически до нуля. Более того, я открывал еще один экземпляр VS и писал код аналогичный следующему foreach (int i = 0; i<1000; i++) Thread.Sleep(1) и он отрабатывал за секунду, хотя в первом экземпляре наблюдались тормоза. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 10:07 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
Имелось в виду... for (int i = 0; i<1000; i++) Thread.Sleep(1) ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 10:26 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
Может быть есть более стабильный способ реализации следующей логики. Есть последовательно технических событий, которые сохранены в виде журнала с указанием времени с точностью до 1 мсек. Мне необходимо воспроизвести эти события во времени. Если Thread.Sleep не является надежным механизмом, то какой механизм следует использовать в качестве альтернативы?! ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 11:35 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
myauchaЕсть последовательно технических событий, которые сохранены в виде журнала с указанием времени с точностью до 1 мсек. Мне необходимо воспроизвести эти события во времени. С точностью до 1 мсек? Забей ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 12:04 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
Pallaris, в гугл. Системы Реального Времени ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 12:41 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
Roman MejtesPallaris, в гугл. Системы Реального Времени Winforms .NET? Забей ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 13:02 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
Вообще-то, все это я делаю в WPF. Может он свой отпечаток накладывает?! ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 14:27 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
myauchaВообще-то, все это я делаю в WPF. Может он свой отпечаток накладывает?! Thread.Sleep гарантирует, что поток уснет на период, не меньший, чем ты указал. Но он не гарантирует, что поток проснется немедленно после указанного периода ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 14:36 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
myauchaя ... писал код аналогичный следующему for (int i = 0; i<1000; i++) Thread.Sleep(1) и он отрабатывал за секунду Брехня. Если только кто-то не пошаманил с функцией timeBeginPeriod. тынц И вообще, в приличном обществе за использование Thread.Sleep бьют ногами. ЗЫ: хотелось бы видеть, как объявлена is_stop. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 15:33 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
petalvikmyauchaя ... писал код аналогичный следующему for (int i = 0; i<1000; i++) Thread.Sleep(1) и он отрабатывал за секунду Брехня.У меня работает, по крайней мере на Win 7, Core 2 Duo 2GHz, ОЗУ 3Г, 64-разрядная ОС. Ну не выкладывать же видео в самом деле! Придется верить на слово petalvikЕсли только кто-то не пошаманил с функцией timeBeginPeriod. тынц Нет petalvikИ вообще, в приличном обществе за использование Thread.Sleep бьют ногами.Предложите альтернативу petalvikЗЫ: хотелось бы видеть, как объявлена is_stop.Да обычный bool. Он на всем протяжении работы остается false и переключаю я ее только когда собираюсь выходить из приложения, так что она тут не при чем ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 15:59 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
PallarisThread.Sleep гарантирует, что поток уснет на период, не меньший, чем ты указал. Но он не гарантирует, что поток проснется немедленно после указанного периодаЭто я понимаю, но на практике сейчас вижу, что цикл в 1000 итераций со слипом в 1 занимает примерно секунду. Чем-нибудь принципиально отличается this.Dispatcher.Invoke((ThreadStart)delegate() { this.Title = date_time.ToString(); }); от this.Dispatcher.Invoke(new Action(() => this.Title = date_time.ToString())); ? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 16:05 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
myauchaВообще-то, все это я делаю в WPF. Может он свой отпечаток накладывает?! вообще то, это раздел WF, но сути дела это не меняет. ОС Windows, это не система реального времени, если вам нужен немедленный отклик то выбор явно неудачный. Со времен FW.NET 2.0 появилась TPL и использовать Thread, не слишком хорошая идея. В Task'ах, есть специальный метод Wait(ms, cancellationtoken), если потребуется прервать таск в тот момент, когда он ожидает (простаивает). ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 16:40 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
myauchaУ меня работает, Ну не выкладывать же видео в самом деле! Вот этот код что выдаст: Код: c# 1. 2. 3.
myauchaПредложите альтернативуSystem.Timers.Timer. myauchaДа обычный bool.Мои мрачные предчувствия оправдались. Код на помоечку, автора сжечь (можно наоборот). На эту тему сломано много копий. Гуглить, например, volatile. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 16:57 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
Roman Mejtesвообще то, это раздел WF, но сути дела это не меняет. ОС Windows, это не система реального времени, если вам нужен немедленный отклик то выбор явно неудачный. Roman MejtesСо времен FW.NET 2.0 появилась TPL и использовать Thread, не слишком хорошая идея.Если появилась новая функциональность, то это не аргумент, что старая перестала работать. Roman MejtesВ Task'ах, есть специальный метод Wait(ms, cancellationtoken), если потребуется прервать таск в тот момент, когда он ожидает (простаивает).И чем этот Wait лучше Sleep-а?! ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 17:01 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
myaucha, тем, что в качестве аргумента он принимает CancellationToken и может быть прерван по требованию. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 18:20 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
petalvikВот этот код что выдаст: Код: c# 1. 2. 3.
Вот результат Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
petalvikmyauchaПредложите альтернативуSystem.Timers.Timer.Это не альтернатива, а масло масленное petalvikmyauchaДа обычный bool.Мои мрачные предчувствия оправдались. Код на помоечку, автора сжечь (можно наоборот). На эту тему сломано много копий. Гуглить, например, volatile.Вы вообще читаете, что вам отвечают?! Я же написал, что переменная не меняется - она на всем протяжении жизни потока всегда содержит значение false и не оказывает никакого влияния на задержку ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 18:52 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
Roman Mejtesmyaucha, тем, что в качестве аргумента он принимает CancellationToken и может быть прерван по требованию.Я из главного WPF потока создаю дочерний, который циклически по времени читает технические события из файла и отображает их посредством Dispatcher.Invoke в главном окне. Что вы мне рекомендуете прервать в нужны момент?! ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 20:03 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
myauchaВот результат <skip> А вот мой результат вашего кода: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Причина - кто-то или что-то пошаманил с функцией timeBeginPeriod. В WPF значение интервала системного таймера меняются. Почему не стоит разгонять таймер Windows . То есть предугадать продолжительность тика таймера невозможно (если не задавать её самому). myauchapetalvikSystem.Timers.Timer.Это не альтернатива, а масло масленное Это разумная альтернатива. При вызове Thread.Sleep поток спит, продолжая при этом потреблять системные ресурсы (отнимая мегабайт памяти (пусть и виртуальной), заставляя диспетчер потоков обслуживать себя). В то время как Timer один на всю систему, запросы к нему выстраиваются в очередь, и добавление вашего не загрузит систему лишней работой. Длина тика при этом - смотрите выше ссылку. myauchaВы вообще читаете, что вам отвечают?! Я же написал, что переменная не меняется - она на всем протяжении жизни потока всегда содержит значение false и не оказывает никакого влияния на задержку Повторяю: гуглить volatile. Компилятор может выбросить цикл вообще, видя, что переменная не меняется. Он знать не знает, что там происходит в других потоках. В данном конкретном случае такой код может работать, в другом (с другой версией фреймворка/CLR, с другим компилятором) - может не работать. Это очень распространённая ошибка. Было время, я сам писал многопоточный код с обычными булевыми флагами. И он даже работал (иногда). А иногда ломался. Именно поэтому разработчиками дотнета был введён CancellationToken, который является потокобезопасным. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 20:56 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
myaucha, если вы тупо читаете из файла, тогда нафига всё это? откройте файл на чтение и читайте в цикле, если достигли конца потока, то делайте паузу, проверяйте опять на конец потока и если новые данные в файле появятся, то читайте дальше... нафига городить для этого таймер? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 21:18 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
так же есть SystemFileWatcher который может возбуждать событие, если файл был изменён. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 21:19 |
|
Странное поведение потока
|
|||
---|---|---|---|
#18+
А такой результат что выдаст? Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Это разумная альтернатива. При вызове Thread.Sleep поток спит, продолжая при этом потреблять системные ресурсы (отнимая мегабайт памяти (пусть и виртуальной), заставляя диспетчер потоков обслуживать себя). В то время как Timer один на всю систему, запросы к нему выстраиваются в очередь, и добавление вашего не загрузит систему лишней работой. Длина тика при этом - смотрите выше ссылку.У меня поток при слипе не ест процессорное время (про память не знаю, но 1Мб памяти не критично), а вот системный таймер не укладывается в 1 мс Повторяю: гуглить volatile. Компилятор может выбросить цикл вообще, видя, что переменная не меняется. Он знать не знает, что там происходит в других потоках. В данном конкретном случае такой код может работать, в другом (с другой версией фреймворка/CLR, с другим компилятором) - может не работать. Это очень распространённая ошибка. Было время, я сам писал многопоточный код с обычными булевыми флагами. И он даже работал (иногда). А иногда ломался. Именно поэтому разработчиками дотнета был введён CancellationToken, который является потокобезопасным.Сделать отдельные переменные потокобезопасными можно и другими способами, но сейчас вопрос заключается не в этом авторесли вы тупо читаете из файла, тогда нафига всё это? откройте файл на чтение и читайте в цикле, если достигли конца потока, то делайте паузу, проверяйте опять на конец потока и если новые данные в файле появятся, то читайте дальше... нафига городить для этого таймер?Не тупо читаю, а с привязкой ко времени. Файл сформирован и зафиксирован, новые данные в него не поступают. А если быть точным, то файлов несколько и в каждом свои технические события со временем возникновения. Я, по сути, их просто проигрываю ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2015, 23:50 |
|
|
start [/forum/topic.php?fid=20&msg=38960627&tid=1401548]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
40ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
52ms |
get tp. blocked users: |
1ms |
others: | 15ms |
total: | 145ms |
0 / 0 |