Непрерывный асинхронный c эхо-запрос внутри службы Windows - PullRequest
0 голосов
/ 26 мая 2020

Мне нужно постоянно отслеживать список хостов. Через N секунд мне нужно снова проверить список. Итак, я попытался использовать asyn c ping внутри службы Windows.

Я пытался следовать советам из других сообщений, связанных с topi c, но всегда мой сервис останавливается вскоре после его запуска .

Проблема с ожиданием в функции "OnElapsedTime".

Кто-нибудь знает, что не так? Ниже мой код:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Net.NetworkInformation;

namespace PingAsyncService
{
    public partial class HyBrazil_Ping : ServiceBase

    {

        Timer timer = new Timer();
        List<string> IPList = new List<string>();  //List of IPs


        public HyBrazil_Ping()
        {
            IPList.Add("192.168.0.1");
            IPList.Add("192.168.0.254");

            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {

            WriteToFile("Service is started at " + DateTime.Now);
            timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
            timer.Interval = 5000; //number in miliseconds 
            timer.Enabled = true;
        }

        protected override void OnStop()
        {
            WriteToFile("Service is stopped at " + DateTime.Now);
        }

        private async void OnElapsedTime(object source, ElapsedEventArgs e)
        {
            //WriteToFile("Service is recall at " + DateTime.Now);

            var ResultList = await PingAsync();
            foreach(PingReply reply in ResultList)
            {
                WriteToFile(reply.Address.ToString() + ";" + reply.Status.ToString());
            }
        }

        private async Task<PingReply> PingAndProcessAsync(Ping pingSender, string ip)
        {
            var result = await pingSender.SendPingAsync(ip, 2000);
            return result;
        }

        private async Task<List<PingReply>> PingAsync()
        {
            Ping pingSender = new Ping();
            var tasks = IPList.Select(ip => PingAndProcessAsync(pingSender, ip));
            var results = await Task.WhenAll(tasks);
            return results.ToList();
        }

        public void WriteToFile(string Message)
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + "\\Logs";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            string filepath = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\ServiceLog_" + DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
            if (!File.Exists(filepath))
            {
                // Create a file to write to.   
                using (StreamWriter sw = File.CreateText(filepath))
                {
                    sw.WriteLine(Message);
                }
            }
            else
            {
                using (StreamWriter sw = File.AppendText(filepath))
                {
                    sw.WriteLine(Message);
                }
            }
        }
    }
}

Большое спасибо!

1 Ответ

2 голосов
/ 30 мая 2020

В одном из комментариев вы упомянули сообщение об ошибке: «Асинхронный вызов уже выполняется. Он должен быть завершен или отменен, прежде чем вы сможете вызвать этот метод».

Скорее всего, объект Ping делает не допускать одновременных асинхронных вызовов. Использование нового объекта Ping каждый раз при каждом вызове может помочь, как показано ниже.

private async Task<List<PingReply>> PingAsync()
{
    // Ping pingSender = new Ping();
    var tasks = IPList.Select(ip =>
    {
        using (var p= new Ping())
        {
            return PingAndProcessAsync(p, ip);
        }
    });
    var results = await Task.WhenAll(tasks);
    return results.ToList();
}
...