C # Windows Service Events

Indlæg af Hanne Mølgaard Plasc

Problem



Så jeg knuser bare her her intet produktionen bare bevis for koncept med min første Windows-service.


Jeg forsøger i det væsentlige at skabe en windows service, der sidder som lytteren for en signalr forbindelse. I det væsentlige vil jeg have et Windows-program og en Windows-tjeneste. Gevinstjenesten håndterer tilslutning til signalr hub og på signalr opfordrer brand en begivenhed. Windows-programmet vil lytte til disse begivenheder og udføre handlinger baseret på dem.


I øjeblikket kan jeg ikke få det til at fungere. Jeg har aldrig arbejdet med arrangementer eller Windows-tjenester før. I mine windows ansøgning mine hændelser aldrig ramt deres brud punkter, så godt jeg logger en fejl med null reference undtagelse fra



  ConnectToHub ()



Okay, hvis jeg kommenterer metodemetoden OnConnected (), logger jeg en vellykket forbindelse til navet. Jeg har aldrig arbejdet med begivenheder før det er min fejl med begivenhederne?


Jeg debatterede, at denne tilgang var en smule overkill. Men for mig var det et bevis på konceptet, at jeg kunne finde en brug til en lang løbende windows service og tilføje nogle begivenheder i blandingen.


Kode for service:


public delegate void MessageRecievedEventHanlder(object sender, MessageRecievedArgs e);
public delegate void ConnectedToHubEventHandler(object sender, ConnectedArgs e);
public partial class SignalRService : ServiceBase
{

    IHubProxy \_hub;
    HubConnection connection;
    string url = @"http://localhost:8080/";
    private Message LastMessage;
    public static event MessageRecievedEventHanlder NewMessage;

    protected virtual void OnNewMessage(MessageRecievedArgs e)
    {
        NewMessage(null, e);
    }

    public static event ConnectedToHubEventHandler Connected;

    protected virtual void OnConnected(ConnectedArgs e) {
        System.IO.File.WriteAllText(@"C:UsersBailey MillerDesktopFTPLogg.txt", "Hit OnConnected " + e.Success +" " + Connected != null ? "Isn't null" : "Null event");
        Connected(null, e);

    }

    public SignalRService()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        ConnectToHub().Wait();

    }

    private async Task ConnectToHub()
    {
        try
        {
            //Connecting

            if (connection == null)
            {
                connection = new HubConnection(url);
            }
            if (\_hub == null)
            {
                \_hub = connection.CreateHubProxy("ChatHub");
            }

            await connection.Start();

            //Connected

            //Configure all the incoming options
            \_hub.On<Message>("RecieveMessage", IncomingMessage);
            System.IO.File.WriteAllText(@"C:UsersBailey MillerDesktopFTPSucces.txt", "Connected");
            OnConnected(new ConnectedArgs(true));

        }
        catch (Exception ex)
        {
            //Failed
            //OnConnected(new ConnectedArgs(false));
            System.IO.File.WriteAllText(@"C:UsersBailey MillerDesktopFTPFail.txt", "Failed to connect " + ex.Message.ToString());
        }

    }

    private void IncomingMessage(Message state)
    {
        DateTime? lmt;
        //Determine if has lastmessagetime
        if (LastMessage == null) {
            lmt = null;
        }
        else {
            lmt = LastMessage.RecievedAt;
        }

        LastMessage = state;

        //New Message
        //OnNewMessage(new MessageRecievedArgs(state, lmt));
    }

    protected override void OnStop()
    {
    }
}

public class MessageRecievedArgs : EventArgs
{
    public Message NewMessage { get; }
    public DateTime? LastMessageTime { get; }

    public MessageRecievedArgs(Message msg, DateTime? lmt) {
        this.NewMessage = msg;
        this.LastMessageTime = lmt;
    }
}

public class ConnectedArgs : EventArgs {
    public bool Success { get; }

    public ConnectedArgs(bool suc) {
        this.Success = suc;
    }
}


Min Windows ansøgning fra nu:


public MainWindow()
    {
        InitializeComponent();
        SignalRService.SignalRService.NewMessage += SignalRService\_NewMessage;
        SignalRService.SignalRService.Connected += SignalRService\_Connected;
    }

    private void SignalRService\_Connected(object sender, SignalRService.ConnectedArgs e)
    {
        throw new NotImplementedException();
    }

    private void SignalRService\_NewMessage(object sender, SignalRService.MessageRecievedArgs e)
    {
        throw new NotImplementedException();
    }

Bedste reference


Dit spørgsmål er lidt bredt, du beskriver ikke præcis, hvad der ikke virker, så jeg gætter på, at når du starter din tjeneste, står det 'starter ...' i lang tid, og til sidst får Windows Service Manager dig en Fejl ved at sige, at din tjeneste ikke startede i tide. Problemet er, at OnStart() forventes at returnere. Du kan ikke blokere tråden der med Wait() opkaldet. Mit forslag ville være at gyde en ny baggrundstråd her for at udføre ventetiden og derefter afslutte. Det burde få dig forbi den første forhindring.


Som en anden side ... Du kan tilføje en almindelig hovedmetode til et Windows-serviceprojekt, ændre projekttypen til Console Application og køre det på den måde for at reducere din debugging-cykeltid. Så når du er sikker på, at det grundlæggende fungerer, skal du ændre projekttype tilbage til Windows Service og installere den.


EDIT: Nu hvor du har en bedre fejlbeskrivelse, ser jeg det virkelige problem. Spørgsmålet er, at du hæver en begivenhed uden at tjekke for null først. Begivenhedsfelterne er null, indtil du vedhæfter en lytter. Så skift din kode som følger:


protected virtual void OnConnected(ConnectedArgs e) {
    System.IO.File.WriteAllText(@"C:UsersBailey MillerDesktopFTPLogg.txt", "Hit OnConnected " + e.Success +" " + Connected != null ? "Isn't null" : "Null event");

    ConnectedToHubEventHandler connectedEvent = Connected;
    if (connectedEvent != null) // This event might be null, so check first
        connectedEvent(null, e);

}