IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Avis entre service Windows et Thread séparé


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2012
    Messages
    337
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2012
    Messages : 337
    Par défaut Avis entre service Windows et Thread séparé
    Bonjour,
    J'ai créé une application WPF qui est composée de deux parties :
    • Un "serveur" qui écoute un port en TCP IP et qui stocke les données dans une base SQLite
    • Une interface qui permet d'afficher les données

    Après avoir terminé mon application, je me suis posé la question de la disponibilité des données.
    Je me suis rendu compte qu'il serait intéressant de continuer à enregistrer mes données même si mon application n'est pas lancée.
    D'où ma question sur la création d'un service Windows qui s'occuperait de la récupération, du traitement et de la mise en base.
    Je précise que l'ordinateur sur lequel doit tourner le programme est en marche en permanence.

    Donc, mes questions :
    Pensez vous que cette architecture soit judicieuse?
    Si oui, est ce qu'il y a des précautions particulières à prendre (optimisation des ressources,...) dans la création d'un service (je n'en ai jamais fait )

    Merci pour vos réponses éclairées.

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    oui c'est judicieux

    c'est comme une application avec ui mais sans ui, donc il n'y a pas de précautions de plus
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2012
    Messages
    337
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2012
    Messages : 337
    Par défaut
    Bonsoir Pol63,
    Merci pour ta réponse.
    Ca me fait plaisir de voir que tu es toujours actif.
    Je n'avais pas posté depuis bien longtemps

  4. #4
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 941
    Par défaut
    Oui, dans ce cas là c'est une bonne idée. C'est un modèle d'architecture qu'on voit lorsqu'on a un service qui doit tourner en tâche de fond et auquel on peut accéder en passant par une interface graphique ou bien que peut joindre un autre service (j'ai en tête l'exemple de Docker Desktop). Pour cela tu faire peut mettre ton service dans une application console avec le modèle des hosted service.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using Monitor;
     
    await Host
        .CreateApplicationBuilder()
        .AddServices()
        .Build()
        .RunAsync();
     
    static class Setup
    {
        internal static HostApplicationBuilder AddServices(this HostApplicationBuilder builder)
        {
            builder.Services
                .AddSingleton<IPortListener, MockPortListener>()
                .AddTransient<IDataService, MockDataService>()
                .AddHostedService<PortMonitorHostedService>();
            return builder;
        }
    }
     
    namespace Monitor
    {
        public interface IPortListener
        {
            Task RequestPortAsync();
            Task ReleasePortAsync();
            event EventHandler<string> MessageReceived;
        }
     
        public class MockPortListener : IPortListener
        {
            public Task RequestPortAsync() => Task.CompletedTask;
            public Task ReleasePortAsync() => Task.CompletedTask;
            public event EventHandler<string>? MessageReceived;
     
        }
     
        public interface IDataService { Task SaveAsync(string data); }
     
        public class MockDataService : IDataService
        {
            public Task SaveAsync(string data) => Task.CompletedTask;
        }
     
        public sealed class PortMonitorHostedService : IHostedService
        {
            private readonly IPortListener _listener;
            private readonly IDataService _service;
     
            public PortMonitorHostedService(IPortListener listener, IDataService service)
            {
                _listener = listener;
                _service = service;
                _listener.MessageReceived += OnMessageReceived;
            }
     
            public async Task StartAsync(CancellationToken cancellationToken) => await _listener.RequestPortAsync();
     
            public async Task StopAsync(CancellationToken cancellationToken) => await _listener.ReleasePortAsync();
     
            private async void OnMessageReceived(object? sender, string message) => await _service.SaveAsync(message);
        }
    }
    Je n'ai aucune idée de ton architecture exacte, mais je donne ici un exemple de la façon de faire. Ensuite, il te faudra voir comment tu veux faire communiquer ton application graphique avec ton service. Ça peut se faire via une api web (voir template web api) ou par un système plus particulier, comme les pipes (anonyme ou nommé) et bien un protocole RPC (Remote Procedure Call). Tu peux voir aussi si le service doit être lancé indépendamment ou si tu donnes l'option de le lancer à partir de l'application graphique.

  5. #5
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    Citation Envoyé par Rainui Voir le message
    Bonsoir Pol63,
    Merci pour ta réponse.
    Ca me fait plaisir de voir que tu es toujours actif.
    Je n'avais pas posté depuis bien longtemps
    ^^

    selon si tu es en framework 4.x ou .net core 3 à 9 c'est un peu différent dans le code (mais pas dans le fonctionnement) (le code de noxen est pour .net core, sinon y a des exemples sur le net)
    sc.exe (utilitaire windows) permet d'installer un exe en tant que service
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2012
    Messages
    337
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2012
    Messages : 337
    Par défaut
    Je viens de regarder pour créer un service, ça n'a effectivement pas l'air bien compliqué.
    Je vous remercie pour vos réponses qui me conforte dans l'idée.
    Merci @Noxen pour l'exemple de code.

  7. #7
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    En termes de précautions, il y a quand même la gestion des IDisposable à bien bétonner, ainsi que l'allocation mémoire.

    En effet, une application avec UI, généralement elle ne reste allumée que quelques heures, le temps d'utilisation du PC, et même souvent pas en permanance.
    Par cosnéquent, si t'as une fuite mémoire ou des locks sur des ressources qui ne sont jamais releasés (ou très tardivement) tu ne t'en rends pas forcément compte.
    Au pire, quand ça commence à trop rammer, tu fermes l'appli et tu la relances.

    Pour la partie service Windows, c'est un peu plus gênant, car il tourne 24/24 7/7 donc la moindre ressource par bien gérée, tu risques de ne jamais la rendre, et ainsi finir par avoir une surcharge importante du serveur pour rien.
    Accessoirement le Service Windows risque d'avoir un impact plus important sur les ressources qu'une application utilisateur et donc là où ton appli s econtenterait de rammer sans forcément bloquer le serveur, le service, lui, peut amener Windows au blocage.

    Donc par exemple, dans le genre de truc à pas faire, c'est de te dire "ok, tout ce que je reçois à stocker dans ma base SQLite je le charge en mémoire dans une List<T> ou autre objet, et vu que je sais facilement retrouver la denrière ligne, je m'amuse jamais à purger les vieilles données.
    Ou alors un Bdd.Open() au début du programme et un Bdd.Close() à la fin (donc dans 3 ans).
    => Pendant ce temps la base SQLite est lockée, et impossible de la sauvegarder, quant aux snapshot du disque tu n'as aucune certitude qu'ils ne contiendront pas une base corrupue puisqu'elle est en permanance en cours d'utilisation, avec potentiellement des données dans le cache d'écriture non flushées.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Service windows et thread
    Par souhail72 dans le forum Général Dotnet
    Réponses: 3
    Dernier message: 12/07/2016, 09h17
  2. Réponses: 15
    Dernier message: 15/10/2012, 12h28
  3. Différence entre un service WCF hosté par Windows Form et par service Windows
    Par BHMath76 dans le forum Windows Communication Foundation
    Réponses: 5
    Dernier message: 26/02/2010, 10h50
  4. long polling entre service windows et un serveur j2EE
    Par sfaxien dans le forum Général Dotnet
    Réponses: 0
    Dernier message: 23/09/2009, 23h25
  5. Réponses: 1
    Dernier message: 04/08/2009, 11h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo