using System; using System.Collections.Generic; using System.Threading.Tasks; using System.Linq; namespace GenerateVDPCycle { class Program { static List tasks = new List(); static void Main(string[] args) { var r = new Random(); for(var i = 1; i <= 48; i++) { var a = new GenCycle(i); a.Start(); tasks.Add(a); } Task.Delay(1000 * 5).Wait(); while (true) { for (var i = 0; i < tasks.Count; i++) { if (i % 10 == 0 && i != 0) Console.WriteLine(); Console.Write(tasks[i].GetSmallStatus() + "|"); } Console.WriteLine(); Task.Delay(1000 * 60 * 10).Wait(); } } } public class GenCycle { private int vdp = 0; private int curCycle = 0; private DateTime factStart = DateTime.Now; private DateTime factEnd = DateTime.Now; private DateTime thinkEnd = DateTime.Now; private bool cycle = false; private Task taskCycle = null; public GenCycle(int vdp) { this.vdp = vdp; } public bool GetCurrCycle() { try { using (var db = new DB.VdpDB()) { var tmp = (from u in db.Cycles where u.NumVdp == vdp orderby u.FactStart descending select u).FirstOrDefault(); if (tmp == null) { curCycle = 0; return false; } curCycle = tmp.NumCycle; factStart = tmp.FactStart; factEnd = tmp.FactEnd; } } catch (Exception e) { Console.WriteLine(e.Message); return false; } return true; } public void GetNextCycle() { var r = new Random(); var a = r.Next(100); switch (curCycle) { case 0: curCycle = (a < 50) ? 14 : 2; break; case 1: curCycle = 2; break; case 2: curCycle = 5; break; case 5: curCycle = 6; break; case 6: curCycle = 7; break; case 7: curCycle = (a < 20) ? 5 : 8; break; case 8: curCycle = 9; break; case 9: curCycle = 10; break; case 10: curCycle = 11; break; case 11: curCycle = 12; break; case 12: curCycle = 0; break; case 14: curCycle = 15; break; case 15: curCycle = 16; break; case 16: curCycle = 1; break; default: curCycle = 0; break; } } public void GetTimeStart() { factStart = factEnd; } public void GetTimeThinkEnd() { switch (curCycle) { case 0: thinkEnd = factStart.AddMinutes(15); break; case 1: thinkEnd = factStart.AddMinutes(15); break; case 2: thinkEnd = factStart.AddMinutes(10); break; case 5: thinkEnd = factStart.AddMinutes(13); break; case 6: thinkEnd = factStart.AddMinutes(7); break; case 7: thinkEnd = factStart.AddMinutes(5); break; case 8: thinkEnd = factStart.AddMinutes(10); break; case 9: thinkEnd = factStart.AddMinutes(5); break; case 10: thinkEnd = factStart.AddMinutes(60); break; case 11: thinkEnd = factStart.AddMinutes(15); break; case 12: thinkEnd = factStart.AddMinutes(30); break; case 14: thinkEnd = factStart.AddMinutes(10); break; case 15: thinkEnd = factStart.AddMinutes(20); break; case 16: thinkEnd = factStart.AddMinutes(15); break; default: thinkEnd = factStart.AddMinutes(15); break; } } public void GetTimeFactEnd() { var r = new Random(); var sec = 0; switch (curCycle) { case 0: sec = r.Next(7 * 60) - (5 * 60); factEnd = thinkEnd.AddSeconds(sec); break; case 1: sec = r.Next(3 * 60) - (2 * 60); factEnd = thinkEnd.AddSeconds(sec); break; case 2: sec = r.Next(11 * 60) - (1 * 60); factEnd = thinkEnd.AddSeconds(sec); break; case 5: sec = r.Next(4 * 60) - (3 * 60); factEnd = thinkEnd.AddSeconds(sec); break; case 6: sec = r.Next(4 * 60) - (3 * 60); factEnd = thinkEnd.AddSeconds(sec); break; case 7: sec = r.Next(7 * 60) - (2 * 60); factEnd = thinkEnd.AddSeconds(sec); break; case 8: sec = r.Next(11 * 60) - (1 * 60); factEnd = thinkEnd.AddSeconds(sec); break; case 9: sec = r.Next(2 * 60) - (1 * 60); factEnd = thinkEnd.AddSeconds(sec); break; case 10: sec = r.Next(40 * 60) - (30 * 60); factEnd = thinkEnd.AddSeconds(sec); break; case 11: sec = r.Next(5 * 60) - (3 * 60); factEnd = thinkEnd.AddSeconds(sec); break; case 12: sec = r.Next(20 * 60) - (10 * 60); factEnd = thinkEnd.AddSeconds(sec); break; case 14: sec = r.Next(11 * 60) - (1 * 60); factEnd = thinkEnd.AddSeconds(sec); break; case 15: sec = r.Next(4 * 60) - (3 * 60); factEnd = thinkEnd.AddSeconds(sec); break; case 16: sec = r.Next(4 * 60) - (3 * 60); factEnd = thinkEnd.AddSeconds(sec); break; default: sec = r.Next(7 * 60) - (5 * 60); factEnd = thinkEnd.AddSeconds(sec); break; } } public bool SaveToDB() { try { using (var db = new DB.VdpDB()) { var tmp = new DB.Cycle() { NumVdp = vdp, NumCycle = curCycle, FactStart = factStart, FactEnd = factEnd, ThinkEnd = thinkEnd }; db.Cycles.Add(tmp); db.SaveChanges(); } } catch (Exception e) { Console.WriteLine(e.Message); return false; } return true; } public void Start() { cycle = true; taskCycle = this.Cycle(); } public void Stop() { cycle = false; taskCycle.Wait(); } async public Task Cycle() { while (cycle) { if (GetCurrCycle()) { if(DateTime.Now >= factEnd) { /*if (vdp == 1) Console.WriteLine("Generate next cycle.");*/ GetNextCycle(); GetTimeStart(); GetTimeThinkEnd(); GetTimeFactEnd(); while (!SaveToDB()) { Console.WriteLine("VDP " + vdp.ToString("D2") + ": Can't connect to DB."); await Task.Delay(5000); } } } else { /*if (vdp == 1) Console.WriteLine("Generate new cycle.");*/ GetTimeStart(); GetTimeThinkEnd(); GetTimeFactEnd(); while (!SaveToDB()) { Console.WriteLine("VDP " + vdp.ToString("D2") + ": Can't connect to DB."); await Task.Delay(5000); } } while (cycle && (DateTime.Now < factEnd)) { var secAwait = (factEnd - DateTime.Now).TotalSeconds; /*if(vdp == 1) Console.WriteLine("Time to cycle update " + secAwait.ToString());*/ if (secAwait >= 5) { /*if (vdp == 1) Console.WriteLine("Delay 5 sec");*/ await Task.Delay(5000); } else { /*if (vdp == 1) Console.WriteLine("Delay last secs");*/ await Task.Delay(Convert.ToInt32(Math.Ceiling(secAwait)) * 1000); } } } } public string GetSmallStatus() { return vdp.ToString("D2") + "-" + curCycle.ToString("D2"); } } }