Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
4 / 4 / 3
Регистрация: 11.04.2014
Сообщений: 175

Разное поведение приложения при запуске из IDE и скомпилированного .exe

06.04.2022, 10:28. Показов 1542. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго утра/дня/вечера!
Суть вопроса такова: приложение отправляет и получает какие-либо значения по udp с определённой частотой.
Отправляю:
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
27
28
29
30
31
32
33
34
35
    public class Send
    {
        private UdpClient Client;
        private ulong Counter = 0;
 
        private CancellationTokenSource Cancel;
        private CancellationToken CancelToken;
 
        private double _Speed = 1;
        public double Speed { get => _Speed; set => _Speed = value; }
        public Send()
        {
            Client = new UdpClient();
 
            Cancel = new CancellationTokenSource();
            CancelToken = Cancel.Token;
 
            Task.Run(() => Running());
        }
 
        public void Running()
        {
            while (!CancelToken.IsCancellationRequested)
            {
                Client.Send(BitConverter.GetBytes(Counter++), 8, new IPEndPoint(IPAddress.Parse("192.168.1.72"), 53000));
 
                int SleepTime = 1000 / (int)(100 * Speed);
                Thread.Sleep(SleepTime);
 
                Logger.PostMessage().Debug($"Speed: {SleepTime}");
            }
        }
 
        ~Send() => Cancel.Cancel();
    }
Получаю:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    public class Recive
    {
        private UdpClient Client;
        private IPEndPoint ReciveAddress;
 
        private CancellationTokenSource Cancel;
        private CancellationToken CancelToken;
 
        public ulong RecivedData { get; set; }
 
        public Stopwatch Watch;
 
        public Recive()
        {
            Client = new UdpClient(53000);
            Watch = new Stopwatch();
 
            Cancel = new CancellationTokenSource();
            CancelToken = Cancel.Token;
 
            ReciveAddress = new IPEndPoint(IPAddress.Any, 53000);
 
            Task.Run(() => Running());
        }
 
        public void Running()
        {
            while (!CancelToken.IsCancellationRequested)
            {
                if (Client.Available > 0)
                {
                    RecivedData = BitConverter.ToUInt64(Client.Receive(ref ReciveAddress));
                    Logger.PostMessage().Debug($"Recived value: {RecivedData} Time: {Watch.ElapsedMilliseconds}");
                    Watch.Restart();
                }
            }
        }
 
        ~Recive() => Cancel.Cancel();
    }
Остальное:
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
27
28
29
30
31
32
33
34
35
36
37
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Net;
    using System.Net.Sockets;
    using System.Collections.Concurrent;
    using System.Threading;
    using GalaSoft.MvvmLight;
    using System.Diagnostics;
    public class Bridge
    {
        private Send Instance;
        private Recive Reciver;
        public double Speed { get => Instance is null ? 0 : Instance.Speed; set => Instance.Speed = value; }
 
        public Bridge()
        {
            Instance = new Send();
            Reciver = new Recive();
        }
    }
 
    public partial class MainWindow : Window
    {
        public MainWindow() => InitializeComponent();
    }
.xaml:
XML
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
27
28
29
30
<Window x:Class="PlayerTester.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PlayerTester"
        mc:Ignorable="d"
        Title="MainWindow" Height="100" Width="600">
 
    <Window.DataContext>
        <local:Bridge />
    </Window.DataContext>
    
    <Grid>
 
        <StackPanel Orientation="Horizontal">
            <TextBlock HorizontalAlignment="Right" VerticalAlignment="Top" Margin="10, 10, 0, 0" 
                       Text="Playing speed: "/>
            <Slider Name="SpeedSlider"
                Height="25" Width="350" Margin="10, 10, 0, 0" VerticalAlignment="Top" 
                AutoToolTipPlacement="BottomRight" AutoToolTipPrecision="2" TickPlacement="BottomRight" IsSnapToTickEnabled="True"
                Minimum="0.25" Maximum="10.00" Ticks="0.25, 0.50, 0.75, 1.00, 5.00, 10.00" Value="{Binding Speed}">
            </Slider>
            
            <TextBlock HorizontalAlignment="Right" VerticalAlignment="Top" Margin="10, 10, 0, 0" 
                       Text="{Binding ElementName=SpeedSlider, Path=Value}"/>
        </StackPanel>
 
    </Grid>
</Window>
При запуске из Visual Studio всё работает в соответствии с ожиданиями.
НО!
При запуске скомпилированного .exe (x86/x64 Debug/Relese без разницы) и уменьшении задержки потока (увеличении частоты передачи данных) всё

Добавлено через 6 минут
Продолжение...
всё работает,
а при уменьшении задержки - ничего не происходит. Реальная задержка не изменяется, однако, значение отвечающих за это переменных изменяется (проверено ведением log'a).
При взаимодействии со слайдером, отвечающим за получение значения, частота временно подскакивает, а потом возвращается к предыдущим значениям (без изменения значения соответствующих переменных).
Как такое может быть?
Может, у кого есть мысли?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.04.2022, 10:28
Ответы с готовыми решениями:

Visual Studio 2010 разное поведение программы при запуске *.exe и из VS
Может кто подскажет, как такое может быть, что когда запускаю программу, из VS, все работает нормально, но если запустить exe файл иногда...

Visual Studio 2010 разное поведение программы при запуске *.exe и из VS
Уважаемые знатоки, столкнулся с проблемой! Программа ведет себя по-разному если её запускать из VS и если её запускать через проводник...

FileNotFoundError: [WinError 3], при запуске скомпилированного .exe файла
Доброе время суток. Система Windows 7 (32), Python 3.4 После компиляции через cx_Freeze, получаю .exe который выдает ошибку...

8
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
06.04.2022, 11:04
Цитата Сообщение от QuickPro Посмотреть сообщение
Как такое может быть?
Перво-наперво синхронизируйте доступ к свойству Speed, т.к. вы его читаете и изменяете из разных потоков.

Как вы определяете, что частота входящих сообщений изменяется?
Не исключено, что затор где-то в реализации Logger, код которого тут не представлен.
Сообщения могут прилетать и чаще, а логгер просто не успевает их выводить.
1
4 / 4 / 3
Регистрация: 11.04.2014
Сообщений: 175
06.04.2022, 11:15  [ТС]
частоту замеряю обычным Stopwatch и вручную (считаю время полёта пакета в Wireshark)
logger - nuget'овский serilog

Добавлено через 6 минут
Конструкция типа:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        public double Speed 
        { 
            get
            {
                lock (GetLocker)
                {
                    return _Speed;
                }        
            }
            set
            {
                lock (SetLocker)
                {
                    _Speed = value;
                }
            } 
        }
не помогает (если я правильно понял про "синхронизацию свойства")
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
06.04.2022, 11:18
Цитата Сообщение от QuickPro Посмотреть сообщение
если я правильно понял про "синхронизацию свойства"
Правильно поняли, но оставьте новый вариант — даже если "не помогает" — не будет других проблем в будущем.

Цитата Сообщение от QuickPro Посмотреть сообщение
частоту замеряю обычным Stopwatch и вручную (считаю время полёта пакета в Wireshark)
Какая частота?

Добавлено через 1 минуту
Цитата Сообщение от QuickPro Посмотреть сообщение
logger - nuget'овский serilog
Куда лог пишется?
1
4 / 4 / 3
Регистрация: 11.04.2014
Сообщений: 175
06.04.2022, 11:21  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
Сообщения могут прилетать и чаще, а логгер просто не успевает их выводить.
В том-то и дело, что поток, из которого я читаю свойство, получает верные значения, а не выполняется сама задержка (но выполняется, если я непрерывно кликаю на ползунок слайдера)

Добавлено через 1 минуту
Цитата Сообщение от kolorotur Посмотреть сообщение
Куда лог пишется?
На SSD

Добавлено через 57 секунд
Цитата Сообщение от kolorotur Посмотреть сообщение
Какая частота?
На частоте 25-100Hz отрабатывает правильно
выше - нет
но в IDE отрабатывает корректно на всех частотах
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
06.04.2022, 11:31
Лучший ответ Сообщение было отмечено QuickPro как решение

Решение

Цитата Сообщение от QuickPro Посмотреть сообщение
выше - нет
Обычно Thread.Sleep ограничен разрешением системного таймера, которое на настольных версиях Windows в районе 15мс.
Если устанавливать время ожидания меньше этого промежутка, то оно не гарантируется и скорее всего будет 14-15мс.
Попробуйте вместо Thread.Sleep использовать мультимедийный таймер (первый попавшийся нугет: Haukcode.HighResolutionTimer) — не исключено, что при отладке он и используется.
1
4 / 4 / 3
Регистрация: 11.04.2014
Сообщений: 175
06.04.2022, 12:01  [ТС]
что-то не могу понять, как его использовать
просто засыпает на WaitForTrigger() и всё
ни событий, ни состояний не могу найти
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
06.04.2022, 12:35
Лучший ответ Сообщение было отмечено QuickPro как решение

Решение

Цитата Сообщение от QuickPro Посмотреть сообщение
не могу понять, как его использовать
Установите период и запустите. Если скорость изменится, то перезапустите.
Как-то так:
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
27
28
29
private int Period => 1000 / (int)(100 * Speed);
 
public void Running()
{
    Stopwatch sw = new();
    using var timer = new HighResolutionTimer();
 
    double currentSpeed = Speed;
    timer.SetPeriod(Period);
    timer.Start();
    while (!CancelToken.IsCancellationRequested)
    {
        Client.Send(BitConverter.GetBytes(Counter++), 8, new IPEndPoint(IPAddress.Parse("192.168.1.72"), 53000));
 
        if (currentSpeed != Speed)
        {
            currentSpeed = Speed;
            timer.Stop();
            timer.SetPeriod(Period);
            timer.Start();
        }
 
        sw.Restart();
        timer.WaitForTrigger();
        sw.Stop();
 
        Logger.PostMessage().Debug($"Period: {Period}, slept for {sw.ElapsedMilliseconds}");
    }
}
До кучи добавил отслеживание задержки в логах.
1
4 / 4 / 3
Регистрация: 11.04.2014
Сообщений: 175
06.04.2022, 13:27  [ТС]
сделал через:
Кликните здесь для просмотра всего текста

сейчас проверю, но первые результаты многообещающие

Добавлено через 51 минуту
kolorotur, Ваш вариант оказался шустрее
Получилось!
Спасибо за помощь!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.04.2022, 13:27
Помогаю со студенческими работами здесь

Разное поведение при запуске из консоли и systemd (Fedora)
Под Windows код работает, сейчас переношу на Fedora 24. Там тоже работает, но нужен автостарт, который пытаюсь сделать через systemd. ...

Различное поведение программы при запуске из-под VisualStudio и exe файла при Debug параметре
Столкнулся с непонятной для меня вещью: при запуске этого кода using (var fs = new FileStream(&quot;Empty.sgy&quot;,...

При запуске приложения из IDE обрезаются края окон
Сегодня какой-то баг появился, раньше не было такого. При запуске приложения из MS Visual Studio 2013 стали обрезаться края окон справа и...

Ошибка при запуске exe приложения
Доброго времени суток. Возникла следующая проблема: при попытке запуска exe приложения вылазит ошибка: точка входа в процедуру...

Ошибка при запуске приложения rocksmith2014.exe
Здравствуйте, ошибка при запуске приложения, лог ниже. Windows недавно установлена, все обновления есть, sp1, IE обновлен, драйвера свежие....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru