Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
 Аватар для Hermein
99 / 43 / 16
Регистрация: 25.10.2011
Сообщений: 246
.NET 4.x

Снять нагрузку с CPU

08.10.2016, 22:13. Показов 2059. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть консольное приложение:

C#
1
2
3
4
5
public static Dictionary<string, Api> UserList = new Dictionary<string, Api>();
public static void Main()
{
    new Server();
}
Server - класс реализующий асинхронный сокет сервер

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
public class Server
    {
        public Socket listener = null;
 
        public Server()
        {
            StartListening();
        }
        public ManualResetEvent AllDone = new ManualResetEvent(false);
 
        public void StartListening()
        {
            var localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2246);
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(50);
 
                while (true)
                {
                    AllDone.Reset();                 
                    listener.BeginAccept(AcceptCallback, listener);
                    AllDone.WaitOne();
                }
 
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
 
        public void AcceptCallback(IAsyncResult ar)
        {
            AllDone.Set();
            var listener = (Socket)ar.AsyncState;
            var handler = listener.EndAccept(ar);
            var state = new StateObject { WorkSocket = handler };
            handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReadCallback, state);
        }
 
        public void ReadCallback(IAsyncResult ar)
        {
            var state = (StateObject)ar.AsyncState;
            var handler = state.WorkSocket;
            var bytesRead = handler.EndReceive(ar);
 
            if (bytesRead <= 0) return;
            state.Sb.Append(Encoding.UTF8.GetString(state.Buffer, 0, bytesRead));
            var content = state.Sb.ToString();
            try
            {
                var gh = content.Split(new[] { "\r","\n","\t"," ",":",",","."},StringSplitOptions.RemoveEmptyEntries);
                if (gh.Length > 1)
                {
                    content = "OK";
                    var uid = gh[0];
                    if (!MainClass.UserList.ContainsKey(uid))
                    {
                        MainClass.UserList.Add(uid,new Api(uid, gh[1]));
                    }
                    else 
                    { 
                        MainClass.UserList[uid].Dispose();
                        MainClass.UserList[uid] = new Api(uid, gh[1]);
                    }
                }
                else 
                {
                    content = "NULL";
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
                content = "ERROR";
            }
            Send(handler, content);
        }
 
        void Send(Socket handler, string data)
        {
            try
            {
                byte[] byteData = Encoding.UTF8.GetBytes(data);
                handler.BeginSend(byteData, 0, byteData.Length, 0, SendCallback, handler);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
 
        void SendCallback(IAsyncResult ar)
        {
            try
            {
                var handler = (Socket)ar.AsyncState;
                handler.EndSend(ar);         //End Async      
                handler.Shutdown(SocketShutdown.Both);
                handler.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
    public class StateObject
    {
        // Client  socket.
        public Socket WorkSocket;
        // Size of receive buffer.
        public const int BufferSize = 1024;
        // Receive buffer.
        public byte[] Buffer = new byte[BufferSize];
        // Received data string.
        public StringBuilder Sb = new StringBuilder();
    }
Есть класс Api
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
public class Api:IDisposable
    {
        public Timer timer = new Timer { Interval = 1000 };
        public BackgroundWorker bw = new BackgroundWorker{bw.WorkerSupportsCancellation = true};
 
        public Str5 str5 = new Str5();
        public Str4 str4 = new Str4();
        public Str3 str3 = new Str3();
 
        public Api(string ww, string qq)
        {
            str5.ww= ww;
            str5.qq = qq;
                        str4.FlagStart=true;
 
            timer.Elapsed += (a, b) =>
            {
                str3.GlobalTime++;
                if (str3.timeEnd > 0)
                {
                    str3.timeEnd--;
                }
                                ...
                //еще куча таких же однотипных 
            };
            timer.Start();
            bw.RunWorkerCompleted += (a, b) =>
              {
                MainClass.UserList.Remove(str5.ww);
                timer.Stop();
                return;
              };
            bw.DoWork += (a, b) =>
            {
                while (str4.FlagStart)
                {
                    if (MainClass.Method1(ref str5,ref str4))
                    {
                        if (MainClass.Method2(ref str5, ref str3,str4))
                        {
                            while (str4.FlagStart)
                            {
                                if (str3.Flag1 && str3.EndTime1 <= 0)
                                {  
                                                                    //производим действия
                                }
                                if (str3.Flag2 && str3.EndTime2 <= 0)
                                {  
                                                                    //производим действия
                                }
                                                                ........................................................
                                //еще десяток таймеров и действий
                                
                                if (str4.FlagStart) {  Thread.Sleep(40000); }
                            }
                        }
                    
                    }
                    if (str4.FlagStart) { Thread.Sleep(60 * 1000); }
                    else { break; }
                }
                str4.FlagStart= false;
                MainClass.UserList.Remove(str5.ww);
                timer.Stop();
                bw.CancelAsync();
                return;
            };
            bw.RunWorkerAsync();
 
        }
        public void Dispose()
        {
            timer.Stop();
            timer.Dispose();
            bw.CancelAsync();
            bw.Dispose();
        }
    }
 
 
    public struct Str5
    {
        //куча паблик полей
    }
    public struct Str4
    {
        //куча паблик полей
    }
    public struct Str3
    {
        //куча паблик полей
    }
    public struct Str2
    {
        //куча паблик полей
 
    }
    public struct Str1
    {
        //куча паблик полей
    }
    public class Units
    {
        public string id { get; set; }
        ...
               //куча паблик полей
    }
Вопрос номер 1:
периодически (раз в несколько суток падает Server), без ошибок и тому подобного просто становится недоступен, что в его реализации не так или как отследить его падение? (ps: запросов к нему довольно мало);
Вопрос номер 2:
Просто космическое потребление CPU при 20+ созданных Api классах, каким образом его можно уменьшить?
Если для теста воткнуть такой код, то нагрузка на проц не превышает 4% при 200 классах:

C#
1
2
3
4
5
6
7
8
bw.DoWork += (a, b) =>
            {
                while (true)
                {
                   Thread.Sleep(2000);
                }
            
            };
Вопрос номер 3:
как правильно реализовать многопоточное приложение при минимальной нагрузке на проц при том что для каждого класса Api нужен свой таймер и свой отдельный поток выполнения и количество Api классов может достигать 500 шт.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.10.2016, 22:13
Ответы с готовыми решениями:

Узнать нагрузку CPU/RAM
В общем есть сервер КС, нужно написать программу, которая выводила бы нагрузку на CPU и RAM, запущен ли сервер. В которую сторону мне...

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

Распределить нагрузку на 6-ядерный CPU
Уважаемые программисты, помогите примером кода. StreamReader reader = new StreamReader(path,Encoding.Default); string...

7
Кодогенератор
 Аватар для hepper
200 / 200 / 51
Регистрация: 15.06.2011
Сообщений: 794
09.10.2016, 18:36
Цитата Сообщение от Hermein Посмотреть сообщение
Вопрос номер 3:
как правильно реализовать многопоточное приложение при минимальной нагрузке на проц при том что для каждого класса Api нужен свой таймер и свой отдельный поток выполнения и количество Api классов может достигать 500 шт
самый простой вариант - поставить в строку 34 Thread.Sleep(10);

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

Добавлено через 1 минуту
Цитата Сообщение от Hermein Посмотреть сообщение
Вопрос номер 2:
Просто космическое потребление CPU при 20+ созданных Api классах, каким образом его можно уменьшить?
Если для теста воткнуть такой код, то нагрузка на проц не превышает 4% при 200 классах:
в исходном варианте потоки непрерывно работают ("делают" проверки условий), а во втором случае ничего не делают ("спят"), предоставляя ресурс другим потокам
1
 Аватар для Hermein
99 / 43 / 16
Регистрация: 25.10.2011
Сообщений: 246
09.10.2016, 21:48  [ТС]
hepper, а что если вызовы методов делать как async прямо из таймера, не плодя лишних BackgroundWorker-ов?
Просто у меня вызов всех методов идет непосредственно по-истечению времени EndTime1.. EndTime100500.
просто если в таймере ставить await то он, я как понимаю, будет стопориться до выполнения нужного метода?
0
Кодогенератор
 Аватар для hepper
200 / 200 / 51
Регистрация: 15.06.2011
Сообщений: 794
09.10.2016, 22:00
Hermein, асинхронный подход поидее снимет лишнюю нагрузку при нормальной реализации... чтото конкретное сказать сложно - т.к. не ясно что у вас в коде происходит и для чего это надо...
0
 Аватар для Hermein
99 / 43 / 16
Регистрация: 25.10.2011
Сообщений: 246
09.10.2016, 22:31  [ТС]
hepper, при создании класса Api происходит авторизация на удаленном сервере. Отдельный Api - это отдельный игрок. В while цикле проверяется условие что игрок еще онлайн. Если он оффлайн - то убиваем класс. Если произошла ошибка в каком-то методе то релогиним игрока. Если игрок перезаходит - то класс убивается и создается новый. Таймер ведет обратный отсчет времени для разных событий, возникающих в игре. Для каждого игрока таймеры строго индивидуальны. И если истекло к примеру время EndTime1 то проверяем условия для выполнения действия (bool флаги и дополнительные);
Пример - человек ввел свои данные и авторизовался на сервере, сервер посмотрел сколько времени осталось для сбора ежедневного бонуса и собирал ли его сегодня игрок - если не собирал и таймер истек то у игрока вылетает событие на клиентской части - что пора собрать ежедневный бонус.
Или например для открытия новой карты нужно чтобы была открыта предыдущая карта, у игрока был определенный лвл, и пришло время для открытия - ему вылетает сообщение о том что выполнены все условия для открытия новой карты.
PS: общение с клиентом по WSS, но с ним проблем нет никаких
0
Кодогенератор
 Аватар для hepper
200 / 200 / 51
Регистрация: 15.06.2011
Сообщений: 794
09.10.2016, 22:43
тогда мб имеет смысл сделать все в таймере отдельном - поставить срабатывание например каждую секунду и в обработчике проверять наступление событий посте чего, по необходимости менять триггеры состояния и/или выполнять чтото
0
 Аватар для Hermein
99 / 43 / 16
Регистрация: 25.10.2011
Сообщений: 246
10.10.2016, 02:30  [ТС]
hepper, сделал прототип:

класс Api:

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class Api
    {
        public Timer timer = new Timer {Interval=1000 };
        Info info = new Info();
        public Api(string num)
        {
            info.Num = num;
            info.EndTime=3;
            info.EndTime2 = 7;
            timer.Elapsed += (a, b) => {
                if (info.EndTime > 0)
                {
                    info.EndTime--;
                }
                else 
                {
                    if (!info.FlagEnd1)
                    {
                        info.FlagEnd1=true;
                        var res = MainClass.Task1(info);
                        if (res.Result)
                        {
                            Console.WriteLine(info.Num + " - SUCCESS1!!!");
                        }
                    }
                }
                if (info.EndTime2 > 0)
                {
                    info.EndTime2--;
                }
                else 
                {
                    if (!info.FlagEnd2)
                    {
                        info.FlagEnd2 = true;
                        var res = MainClass.Task2(info);
                        if (res.Result)
                        {
                            Console.WriteLine(info.Num + " - SUCCESS2!!!");
                        }
                    }
                }
            };
            timer.Start();
        }
    }
    public class Info
    {
        public int EndTime { get; set; }
        public bool FlagEnd1 { get; set; }
        public int EndTime2 { get; set; }
        public bool FlagEnd2 { get; set; }
        public string Num { get; set; }
    }
Класс Main:

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
public static void Main(string[] args)
        {
            new Api("1");
            //new Api("2");
            //new Api("3");
            //new Api("4");
            Console.ReadKey();
        }
        public static async Task<bool> Task1(Info info)
        {
            await Task.Delay(1000);
            Console.WriteLine(info.Num+" Task1");
            info.EndTime = 6;
            info.FlagEnd1 = false;
            return true;
        }
        public static async Task<bool> Task2(Info info)
        {
            await Task.Delay(1000);
            Console.WriteLine(info.Num+ " Task2");
            info.EndTime2 = 14;
            info.FlagEnd2 = false;
            return true;
        }
Почему поля класса Info меняются без ключевого слово ref?

Добавлено через 7 минут
При старте 100+ классов будто не работает вовсе

Добавлено через 1 минуту
хотя нет работает но старт откладывается на 3-5 минут

Добавлено через 59 минут
В общем: ничего не откладывается никуда, просто timer перестает работать до завершения методов
0
Эксперт .NET
 Аватар для Usaga
14087 / 9305 / 1348
Регистрация: 21.01.2016
Сообщений: 34,949
10.10.2016, 06:18
Цитата Сообщение от Hermein Посмотреть сообщение
Почему поля класса Info меняются без ключевого слово ref?
А почему они не должны этого делать? Это ведь не С++, тут все ссылочные типы всегда передаются по ссылке. Info нужно передавать с ключевым словом ref только в том случае, если нужно изменить саму ссылку, чтобы ссылалась на другой объект этого класса.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.10.2016, 06:18
Помогаю со студенческими работами здесь

Определить нагрузку приложения на ЦП
Подскажите программу или нативные средства студии,благодаря каким можно смотреть как она грузит процессор. Тест производительности это...

Как ослабить нагрузку проекта на ЦП?
Возникла проблема. Создаю игру с большим числом графических объектов (часть отвечает за картинки, часть за анимации) и при запуске все...

Снять нагрузку с эмиттерного повторителя
Повторитель на кт829а, Uпит 12 вольт и резистор 60 кажется ом. Все работает на до мегагерца, дальше не проверял. Нагружаю лампочкой 20...

Как узнать нагрузку CPU в Android приложении?
Стодкнулся с проблемой по получению информации о нагрузке ЦП. На многих форумах написано, что нужно доставать с ядра линукса с файла...

Как узнать нагрузку на ядро CPU в процентах?
Нужно узнать нагрузку на ядро (в моем случае оно одно), попробовал вот так: ps aux | awk '{s += $3} END {print s &quot;%&quot;}' ...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru