.NET 4.x Снять нагрузку с CPU - C#
Формулировка задачи:
Есть консольное приложение:
Server - класс реализующий асинхронный сокет сервер
Есть класс Api
Вопрос номер 1:
периодически (раз в несколько суток падает Server), без ошибок и тому подобного просто становится недоступен, что в его реализации не так или как отследить его падение? (ps: запросов к нему довольно мало);
Вопрос номер 2:
Просто космическое потребление CPU при 20+ созданных Api классах, каким образом его можно уменьшить?
Если для теста воткнуть такой код, то нагрузка на проц не превышает 4% при 200 классах:
Вопрос номер 3:
как правильно реализовать многопоточное приложение при минимальной нагрузке на проц при том что для каждого класса Api нужен свой таймер и свой отдельный поток выполнения и количество Api классов может достигать 500 шт.
public static Dictionary<string, Api> UserList = new Dictionary<string, Api>(); public static void Main() { new 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(); }
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; } ... //куча паблик полей }
bw.DoWork += (a, b) => { while (true) { Thread.Sleep(2000); } };
Решение задачи: «.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; }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д