Написал программу которая должна раз в секунду проверять ping до двух серверов. Проблема в том, что примерно через 15 минут таски перестают выполняться. В выводе вижу такое:
Ping: 87.250.250.242 Status: Success Time: 17.10.2019 15:18:51
Ping: 8.8.8.8 Status: Success Time: 17.10.2019 15:18:52
Ping: 87.250.250.242 Status: Success Time: 17.10.2019 15:18:52
Поток 0x65f0 завершился с кодом 0 (0x0).
Поток 0x324 завершился с кодом 0 (0x0).
Поток 0x46c4 завершился с кодом 0 (0x0).
Поток 0x5fac завершился с кодом 0 (0x0).
Поток 0x4b00 завершился с кодом 0 (0x0).
Ну и естественно таски никакие исключения не кидают. Хотя вроде должны работать постоянно.
static void Main(string[] args)
{
Run();
Console.ReadKey();
}
private static void PingTimeout(string srv)
{
Console.WriteLine($"Warning! {srv} server timeout, {DateTime.Now}");
}
private static async void Run()
{
Task allTasks = null;
try
{
Task t1 = Task.Run(() => CheckConnection("8.8.8.8", 1000));
Task t2 = Task.Run(() => CheckConnection("87.250.250.242", 1000));
allTasks = Task.WhenAll(t1, t2);
await allTasks;
}
catch(Exception ex)
{
Console.WriteLine($"Critical! {ex.Message}");
Console.WriteLine("IsFaulted: " + allTasks.IsFaulted);
foreach (var inx in allTasks.Exception.InnerExceptions)
{
Console.WriteLine("Внутреннее исключение: " + inx.Message);
}
}
}
private static void CheckConnection(string srvAddress, int interval)
{
TimerCallback timerCallBack = new TimerCallback(PingServer);
Timer timer = new Timer(timerCallBack, srvAddress, 0, interval);
}
private static void PingServer(object obj)
{
MyClass instance = new MyClass();
instance.myEvent += new EventDelegate(PingTimeout);
string target = (string)obj;
Ping ping = new Ping();
int timeout = 1280;
string data = "sjfhksjfdkjsdjfkjsdfskjdhfksh";
byte[] buffer = Encoding.ASCII.GetBytes(data);
PingOptions options = new PingOptions(128, true);
PingReply pingReply;
try
{
pingReply = ping.Send(target, timeout, buffer, options);
Debug.WriteLine($"Ping: {pingReply.Address} Status: {pingReply.Status} Time: {DateTime.Now}");
switch (pingReply.Status)
{
case IPStatus.Success:
//Debug.WriteLine($"success {pingReply.Address}");
break;
case IPStatus.TimedOut:
instance.InvokeEvent(target);
break;
default:
//Debug.WriteLine($"unknown {pingReply.Address}");
break;
}
}
catch(Exception ex)
{
Console.WriteLine($"Critical! exception {ex.Message} at {DateTime.Now}");
}
ping.Dispose();
}
В вашем коде таски (которые Task) завершаются почти мгновенно, по возврату из CheckConnection. Через некоторое время вызовы PingServer создают достаточно много новых объектов, чтобы триггернулась сборка мусора.
На таймеры у вас есть ссылки только из локальных переменных уже завершенного метода, ссылок из корней нет - и сборщик мусора убивает их как недостижимые.
Это типовая ошибка, о ней даже в описании класса Timer упомянуто:
As long as you are using a Timer, you must keep a reference to it. As with any managed object, a Timer is subject to garbage collection when there are no references to it. The fact that a Timer is still active does not prevent it from being collected.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
У меня есть камера "видеонаблюдения" за комнатойВ соседней комнате есть GameObject (монитор) с VideoPlayer ом на котором должна быть ТЕКУЩАЯ запись с камеры
Решил поучиться SQL по книге Алана Бьюли, скачал учебную БД, но не ясно как ее импортировать при помощи DataGrip на бесплатную БД от HerokuБД MySQL
Правильно ли такое оформление запроса? Выводит пустую таблицу при добавлении: HAVING datetime >= DATE_SUB(NOW(), INTERVAL 1 HOUR); Или подскажите как отобрать данные...