c # - Windows service kommunikation og gevindskæring

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har læst mange tutorials/helpdesks (herunder denne) på Windows-tjenester og tråder for at finde ud af den bedste måde at nå nedenstående mål. Jeg kan ikke finde ud af et par ting selv, så nu undrer jeg mig hvis jeg vælger den rigtige måde at gå eller ej, og hvis jeg gjorde det, hvordan implementerer jeg det.


Målet:
Jeg skal udføre 5 separate opgaver i baggrunden, så jeg vil oprette en windows service. Udover tjenesten ønsker jeg en formular ansøgning for at vise information om tjenesten. Fra hvad jeg har læst, skal jeg bruge en sokkelserver til at håndtere kommunikation.


Min plan:



  1. Opret en windows service

  2. Opret en async socket server klasse og start den i onstart metode

  3. Når stikkontakten er korrekt startet og klar, skal du ringe til en metode
    på hovedtjenesten starttasker.

  4. Opret en separat klasse for hver opgave med en executeTask-metode

  5. I startTasks-metoden vil jeg starte en tråd for hver opgave, så de
    kan alle køre simultanious.

  6. Når en opgave har noget at rapportere, skal det kalde en metode på
    hovedtjeneste kaldet sendData (msg)

  7. Senddata-metoden skal kalde en metode i sokkelserver-klassen
    som sender meddelelsen til alle tilsluttede klienter.



Problemet er med 3, 6 og 7 og involverer 'Opkaldsmetode på anden tråd/klasse'.



  • Hvordan kan jeg lade asycn-serveren kalde startTasks-metoden, når den er
    klar

  • Hvordan kan jeg sende data via denne server fra en separat tråd.



Simplefied service:


public partial class SecurityCheck : ServiceBase
    {
        private ComServer \_comServer;
        private CheckRequest \_checkRequest;

        private readonly Thread[] \_threads = new Thread[1];
        private int \_tNr;

        public SecurityCheck()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            \_comServer = new ComServer();
        }

        protected override void OnStop()
        {
            \_comServer.CloseSockets();

            if (\_checkRequest != null)
                \_checkRequest.ServiceStarted = false;

            foreach (Thread t in \_threads)
            {
                if (t != null)
                    t.Join(new TimeSpan(0, 2, 0));
            }
        }

        internal void StartTasks()
        {
            \_checkRequest = new CheckRequest { ServiceStarted = true };
            var st = new ThreadStart(\_checkRequest.ExecuteTask);
            \_threads[\_tNr] = new Thread(st);
            \_threads[\_tNr].Start();
            \_tNr++;
        }

        internal void SendData(string msg)
        {
            \_comServer.SendData(msg);
        }
    }


Simplefied opgave


public class CheckRequest
{
    public bool ServiceStarted;

    public CheckRequest()
    {
        //construct me
    }

    public void ExecuteTask()
    {
        while (ServiceStarted)
        {
            try
            {
                //perform task

                //what to do to send data?
            }
            catch (Exception ex)
            {

            }

            // yield
            if (ServiceStarted)
            {
                Thread.Sleep(new TimeSpan(0, 0, 10));
            }
        }

        Thread.CurrentThread.Abort();
    }
}

Bedste reference


For kommunikationen mellem Tjenesten og Kunderne ville jeg helt sikkert gå med (duplex) WCF i stedet for stikkontakter. Dette vil spare dig for en masse kedelig og fejlfuld kodning. [3]


For det andet lyder det at have en særskilt klasse for hver opgave med en executeTask-metode, som du hagler fra Java-verdenen eller runnable objekter. I C # kan du bare kode opgaverne som separate metoder og starte dem som en opgave, der skal udføres asynkront. Når de har noget at rapportere til klienterne, kan de bare sende det til kunderne selv via en duplexkanal mellem klienterne og serveren. [4] [5]


Brug af WCF og TPL til dette projekt skal stort set løse alle de problemer du beskriver og har dig hjemme i tide til middag. Det kan koste lidt tid nu for at få kendskab til disse nyere teknologier, men det vil spare dig for mange tiders senere ved at have kortere kode, der er lettere at overføre og har mindre plads til fejl.


Hilsen Gert-Jan