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 :

Run R script via c#


Sujet :

C#

  1. #1
    Membre confirmé Avatar de M.Max
    Homme Profil pro
    Inscrit en
    Décembre 2009
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2009
    Messages : 90
    Par défaut Run R script via c#
    Hello,

    Comme intitulé, je cherche à lancer des scripts R via C#. Pour cela j'ai trouvé qlq sources qui utilisent System.Diagnostics.Process :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    System.Diagnostics.Process proc = new System.Diagnostics.Process();
    proc.StartInfo.FileName = "E:/R/bin/Rscript.exe";
    proc.StartInfo.WorkingDirectory = "E:/R/bin/";
    proc.StartInfo.Arguments = "E:/R/bin/test.r";
    proc.StartInfo.UseShellExecute = true;
    proc.StartInfo.RedirectStandardOutput = false;
    proc.Start();
    La question qui en découle : comment récupérer le résultat renvoyé par Rscript.exe ? Y-a-t'il un moyen via ce processus créé ? Ou je dois faire une bidouille type fichier texte ou autre ?

    Merci de vos lumières !

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    327
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 327
    Par défaut
    Bonjour,
    Peut être avec ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    process.StandardOutput.ReadToEnd();
    http://msdn.microsoft.com/fr-fr/libr...ardoutput.aspx

  3. #3
    Membre chevronné
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2011
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2011
    Messages : 610
    Par défaut
    Salut!

    Wakan t'a mis sur la bonne piste.
    Il te suffit de mettre à true les Redirection suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    proc.StartInfo.RedirectStandardOutput = true;
    proc.StartInfo.RedirectStandardError = true;
    proc.Start();
    Pour récupérer le résultat ou l'erreur d'execution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    string resultat = proc.StandardOutput.ReadToEnd();
    string resultatErr = proc.StandardError.ReadToEnd();
    Et voilà

  4. #4
    Membre confirmé Avatar de M.Max
    Homme Profil pro
    Inscrit en
    Décembre 2009
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2009
    Messages : 90
    Par défaut
    Merci pour ses réponses rapides et précises.

    Je test et vous revient !

  5. #5
    Membre confirmé Avatar de M.Max
    Homme Profil pro
    Inscrit en
    Décembre 2009
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2009
    Messages : 90
    Par défaut
    Merci pour ce coup de pouce, ça fonctionne bien.

    Petites questions supplémentaires pour comprendre l'environnement :


    Situation 1 : UseShellExecute = False

    Je passe un script dans Process.Arguments puis je reçois le résultat via le stream Process.StandardOutput. Ca fonctionne parfaitement !
    ==> Comment passer des arguments à une fonction présente dans ce script ? (le script actuel est un simple "print("Hello World....")". Donc par exemple pouvoir faire "print(arg[0])", j'avoue ne pas avoir compris comment utiliser Process.StandardInput pour cela.

    Situation 2 : UseShellExecute = True

    Dans cette situation, les streams StandardInput, StandardOutput et StandardError ne sont pas utilisables. Lorsque je lance Process.Start() sur mon "Hello world", je vois qu'il s'affiche dans une nouvelle console mais celle-ci disparaît immédiatement : comment récupérer le résultat dans ce cas présent ?


    La finalité :

    Je veux utiliser Rscript comme moteur de calcul. C# n'est qu'un wrapper qui va gérer du load balancing sur un cluster d'instances de Rscript. Ceci dit il faut que je puisse passer des paramètres directement de C# à R et l'inverse pour les résultats. Pour une question de performance, je voudrais par exemple lancer 5 process de Rscript puis y executer les scripts que je souhaite, actuellement je suis obligé de killer le process puis le relancer pour obtenir un deuxieme résultat (via le stream StandardOutput), ce qui n'est pas très performant.

    Si j'ai été assez clair dans mes explications, quel est l'avis des experts ?

    Merci de vos lumières !

  6. #6
    Membre chevronné
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2011
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2011
    Messages : 610
    Par défaut
    Citation Envoyé par M.Max Voir le message
    Situation 1 : UseShellExecute = False

    Je passe un script dans Process.Arguments puis je reçois le résultat via le stream Process.StandardOutput. Ca fonctionne parfaitement !
    ==> Comment passer des arguments à une fonction présente dans ce script ? (le script actuel est un simple "print("Hello World....")". Donc par exemple pouvoir faire "print(arg[0])", j'avoue ne pas avoir compris comment utiliser Process.StandardInput pour cela.
    Afin d'utiliser correctement StandardInput, la première chose à faire est de le déclarer à true avant le lancement du process.
    Ensuite pour passer un argument, avant la fermeture du process, utilise la propriété Write de StandartInput. Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    using (StreamReader sr = new StreamReader("Hello Word"))
    {
        process.StandardInput.Write(sr.ReadToEnd());
        process.StandardInput.Flush();
    }
    Citation Envoyé par M.Max Voir le message
    Situation 2 : UseShellExecute = True

    Dans cette situation, les streams StandardInput, StandardOutput et StandardError ne sont pas utilisables. Lorsque je lance Process.Start() sur mon "Hello world", je vois qu'il s'affiche dans une nouvelle console mais celle-ci disparaît immédiatement : comment récupérer le résultat dans ce cas présent ?
    Simplement car lorsque UseShellExecute est à true, tu utilises la fonction ShellExecute qui ne te permet pas les mêmes "avantages" que la fonction CreateProcess (lorsque UseShellExecute es à false). En gros UseShellExecute inclus plusieurs inconvénient comme l'impossibilité de rediriger l'entrée et la sortie standard.

  7. #7
    Membre confirmé Avatar de M.Max
    Homme Profil pro
    Inscrit en
    Décembre 2009
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2009
    Messages : 90
    Par défaut
    Merci pour ces éclairages, j'arrive à manipuler ces process, le lancement des scripts et la récupération des résultats désormais.

    Question subsidiaire : je souhaite passer des données dans ce process, à chaque lancement je veux soumettre une matrice 4000x4000.
    Il y a une contrainte temps-réel, donc passer par une BDD ou un fichier txt me semble proscrit, j'aimerais pouvoir faire transiter l'objet tant qu'il est sur la mémoire vive du process C# au process du script. Une idée ??

  8. #8
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Si les batch que tu exécutes sont des programmes C# que tu as développé, l'utilisation de Thread au lieu de Rscript améliorerait la performance, en particulier un seul chargement par exe appelé et passage direct d'arguments comme objets).

  9. #9
    Membre confirmé Avatar de M.Max
    Homme Profil pro
    Inscrit en
    Décembre 2009
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2009
    Messages : 90
    Par défaut
    Citation Envoyé par Graffito Voir le message
    Si les batch que tu exécutes sont des programmes C# que tu as développé, l'utilisation de Thread au lieu de Rscript améliorerait la performance, en particulier un seul chargement par exe appelé et passage direct d'arguments comme objets).
    Hello,

    Ce sont des scripts R exécutés par Rscript...

    J'ai l'impression de tourner en rond : ma solution actuelle était de créer un ThreadPool, puis de lancer un process Rscript dans chaque Thread pour faire tourner l'algo mais j'ai peur que ça ne soit pas si performant que ça, et ça ne résout pas le problème des données à transmettre au process Rscript.exe

    Comme tu dis, une solution serait de redévelopper l'algo de R à C# mais C# n'est pas naturellement fourni en library math/stat et cela pourrait me prendre un temps considérable.

    Je cherche la solution optimale temps de dev/perf..........

  10. #10
    Membre émérite

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2011
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 487
    Par défaut
    Bonjour,

    As tu considéré F# ? C'est utilisé pour pas mal de librairies scientifiques/mathématiques
    Mon blog sur les technos .NET et Agile -> http://blog.developpez.com/maximepalmisano/

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 18/10/2008, 15h42
  2. problème d'exécution d'un script via ssh
    Par adiljoun dans le forum Shell et commandes GNU
    Réponses: 1
    Dernier message: 21/07/2008, 21h36
  3. [Système] Exécuter un script via PHP
    Par steeve93800 dans le forum Langage
    Réponses: 2
    Dernier message: 03/03/2008, 23h20
  4. [Configuration] limite de temps pour l'éxécution de scripts via php-cli
    Par icer dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 28/05/2007, 12h33
  5. exécution de script via OEM
    Par big1 dans le forum Entreprise Manager
    Réponses: 6
    Dernier message: 25/09/2006, 20h39

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