.NET 4.x Снять нагрузку с CPU - C#

Узнай цену своей работы

Формулировка задачи:

Есть консольное приложение:
public static Dictionary<string, Api> UserList = new Dictionary<string, Api>();
public static void Main()
{
    new Server();
}
Server - класс реализующий асинхронный сокет сервер
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
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 классах:
bw.DoWork += (a, b) =>
            {
                while (true)
                {
                   Thread.Sleep(2000);
                }
            
            };
Вопрос номер 3: как правильно реализовать многопоточное приложение при минимальной нагрузке на проц при том что для каждого класса Api нужен свой таймер и свой отдельный поток выполнения и количество Api классов может достигать 500 шт.

Решение задачи: «.NET 4.x Снять нагрузку с CPU»

textual
Листинг программы
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;
        }

ИИ поможет Вам:


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

Оцени полезность:

6   голосов , оценка 3.667 из 5
Похожие ответы