Question Delegués et thread

Plus d'informations
il y a 15 ans 1 mois #8590 par Arthur
Delegués et thread a été créé par Arthur
Bonsoir,
En ce moment je me suis intéressé au multi-threading et aux délégués dans powershell.

Et je suis tombé sur ce post de laurent : powershell-scripting.com/index.php?optio...58&catid=14#3558

(J'en ai lus d'autres mais celui ci est le plus pertinent)

J'ai donc fait 3 test.

1er test :

[code:1]$code = @\"
using System;
using System.Threading;
public class Program
{
public static void Launch()
{
Thread t = new Thread (WriteY);
t.Start();
}

static void WriteY()
{
for (int i = 0; i < 10; i++)
{
Console.Write (\"y\"«»);
Thread.Sleep(1000);
}
}
}
\"@

Add-Type -TypeDefinition $code
[Program]::Launch();
for($i=0;$i -le 10;$i++) {Write-Host z;Start-Sleep -Seconds 1}
[/code:1]

2em test :

[code:1]$delegate = [Threading.ThreadStart] {for($i=0;$i -le 10;$i++) {Write-Host y;Start-Sleep -Seconds 1}}
$thread = New-Object Threading.Thread -ArgumentList $delegate
$thread.Start()
for($j=0;$j -le 10;$j++) {Write-Host z;Start-Sleep -Seconds 1}[/code:1]

et enfin 3em test qui utilise la fonction New-Delegate du post de Laurent :

[code:1]. ./toto.ps1
$delegate = New-Delegate Threading.ThreadStart {for($i=0;$i -le 10;$i++) {Write-Host y;Start-Sleep -Seconds 1}}
$thread = New-Object Threading.Thread ($delegate)
$thread.Start()
for($j=0;$j -le 10;$j++) {Write-Host z;Start-Sleep -Seconds 1}

[/code:1]


Résultats :

Le 1er et le 3em test marchent.

En revanche comme par hasard celui qui m'intéresse le plus, le 2em crash au niveau du thread.
J'ai un message \"Powershell has stopped working\" cependant la console continue à afficher les \"z\", ce qui veut dire que le thread principale marche.

En comparant les 2 delegate du 2em test et 3em test, j'ai vus qu'ils étaient différents.

Visiblement dans le 2em test powershell a mal instancié le delegate (c'est surement ma faute:blush: )

Bref tout ca pour dire que je me suis mis à recréer la fonction codé par le japonnais moi même histoire de tout comprendre et peut être l'améliorer pour faire un New-Delegate V2, cependant il est fort possible que j'ai oublié un truc dans le script du 2em test mais je n'ai pas trouvé de doc précise mis à part quelques exemples (dont ceux de Laurent)
Du coup je n'arrive pas à savoir ce qu'il se passe derrière quand Powershell V2 instancie le delegate.
Pour le moment dans ma tête ca fait un peu : tu met ton type, ton code et hop c'est magique powershell te fait tout.
Et du coup quand ca bug ben je bloque. :pinch:

Je voulais donc savoir si quelqu'un à des liens ou s'y connait bien dans l'utilisation de delegate en powershell, pour m'aider un peu et m'éviter de recréer la fonction qui va me prendre plusieurs heures et pas mal de maux de têtes.(Même si je trouve ca \"fun\")

Merci beaucoup.

Message édité par: bilbao, à: 25/01/11 21:55

Message édité par: bilbao, à: 25/01/11 22:52<br><br>Message édité par: bilbao, à: 26/01/11 18:17

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 15 ans 1 mois #8591 par Arthur
Réponse de Arthur sur le sujet Re:Delegués et thread
Juste pour dire que j'ai enfin digérer le script (New-Delegate). :cheer:
Je dit bravos à celui qui à écrit la fonction.
Cependant cela ne m'aide toujours pas dans mon problème Pour le moment je cherche à créer manuellement le delegate avec la méthode \&quot;CreateDelegate()\&quot; sans passer par une méthode dynamique et tous ce qui va avec (:cheer:), en gros en plus simple mais je bloque toujours.

Cependant je me dit que avec Powershell V2 on peut le faire.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 15 ans 1 mois #8596 par Arthur
Réponse de Arthur sur le sujet Re:Delegués et thread
Bon au final même le script New-Delegate n'est pas très stable, j'ai des bug et des crash très bizarres.

Dans l'idéal j'aurai voulu exécuter du code powershell dans un autre thread, car certains mes scripts nécessitent que je crée un runspace dans un autre runspace. :whistle:

Par exemple, j'ai codé un client Telnet asynchrone utilisant un runspace pour récupérer les messages du serveur, pour faire en sorte d'utiliser plusieurs connexions telnet en même temps je suis obligé \&quot;d'englober\&quot; chaque connexion dans un runspace.

Comme ca l'utilisateur peut switcher d'une connexion à l'autre rapidement sans perdre de connexion.

Cependant je trouve l'idée de créer des runspace dans un autre runspace fait un peu bricolage.

Aux grands maux les grands moyens. :laugh:

J'ai trouvé un bon compromis exécuter du code C# avec des paramètres dans un autre thread avec un backgroundWorker et le contrôler assez facilement depuis powershell.

Voici un exemple de code que j'ai récupéré et modifié un peu pour l'adapter à powershell:

[code:1]$code = @\&quot;
using System;
using System.Threading;
using System.ComponentModel;

public class Program {
public static BackgroundWorker bw;
public void Launch(String Message) {
bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.DoWork +=bw_DoWork;
bw.ProgressChanged +=
delegate(object sender, ProgressChangedEventArgs e)
{

bw_ProgressChanged(sender,e,Message);
};
bw.RunWorkerCompleted += bw_RunWorkerCompleted;

bw.RunWorkerAsync (\&quot;Hello to worker\&quot;«»);

Console.WriteLine (\&quot;Press Enter in the next 5 seconds to cancel\&quot;«»);
}
public void Cancel()
{
if (bw.IsBusy) bw.CancelAsync();
while(bw.CancellationPending == true) {Thread.Sleep(100); }
}
static void bw_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i &lt;= 100; i += 20) {
if (bw.CancellationPending) {
e.Cancel = true;
return;
}
bw.ReportProgress (i);
Thread.Sleep (1000);
}
e.Result = 123; // This gets passed to RunWorkerCompleted
}
static void bw_RunWorkerCompleted (object sender,
RunWorkerCompletedEventArgs e) {
if (e.Cancelled)
Console.WriteLine (\&quot;You cancelled!\&quot;«»);
else if (e.Error != null)
Console.WriteLine (\&quot;Worker exception: \&quot; + e.Error.ToString());
else
Console.WriteLine (\&quot;Complete - \&quot; + e.Result); // from DoWork
}
static void bw_ProgressChanged (object sender,
ProgressChangedEventArgs e,String Message) {
Console.WriteLine (\&quot;Reached \&quot; + e.ProgressPercentage + \&quot;%\&quot;«»);
Console.WriteLine (\&quot;Message \&quot; + Message);
}
}
\&quot;@

Add-Type -TypeDefinition $code
$obj = New-Object Program
$Message = Read-Host -Prompt \&quot;Enter whatever you like :\&quot;
$obj.Launch($Message)
Read-Host
$obj.Cancel()
[/code:1]<br><br>Message édité par: bilbao, à: 26/01/11 23:59

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 15 ans 1 mois #8620 par Laurent Dardenne
Réponse de Laurent Dardenne sur le sujet Re:Delegués et thread
Bonjour bilbao
bilbao écrit:

Bonsoir,
En ce moment je me suis intéressé au multi-threading et aux délégués dans powershell.

J'ai peu de temps en ce moment pour me pencher sur ce type de discussion, mais c'est tjr très intéressant de savoir si oui ou non on peut utiliser telle ou telle technique sous PS.
De ce que j'ai compris sous PS: multi-threading= PSJob.
Tout le reste sera tjr considéré comme du free style. Je n'ai pas eu le temps de tout lire, mais dans ton premier post si ton code crash PS, à mon avis faut changer ton fusil d'épaule. Et si une fois ceci fait c'est le C# qui l'emporte, bah faut en tirer la conclusion que, à moment donné, il faut faire un choix entre un langage statique, +- proche du système, et Powershell, OUTIL d'automatisation.
Tes derniers scripts penchent du côté \&quot;lumineux\&quot; de la 'force', alias C#.


bilbao écrit:

Et je suis tombé sur ce post de laurent :

Le lien pointe sur un post de 2008, le dernier (2010) précise que la fonction New-Delegate, alias Code-Warrior, n'est plus nécessaire sous PS V2.
Personellement je ne lâche pas l'affaire dés que je rencontre une difficulté, mais de là à générer du code IL sous PS, faut reconnaitre que c'est du code de furieux, certes très utile. Mais, à mon avis, peu de sociétés accepterons de livrer ce type de code en production.
Ceci dit, je suis ravi qu'à ton tour tu enrichisses ce forum :)

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 15 ans 1 mois #8720 par Arthur
Réponse de Arthur sur le sujet Re:Delegués et thread
En fait je me suis rendus compte qu'il est impossible d'exécuter de façon stable 2 codes Powershell en même temps sur la même console ou \&quot;host\&quot;, à cause de la conception même de Powershell, assez souvent un script en multithread génère des erreurs aléatoires, un coup j'ai eu :

\&quot;The '++' operator works only on numbers. The operand is a 'System.Threading.ThreadStart'.
At C:\Users\Toto\Documents\Powershell\test_multithread3.ps1:3 char:72
+ $delegate = New-Delegate Threading.ThreadStart {for($i=0;$i -le 10;$i++ &lt;&lt;&lt;&lt; ){Write-Host y;Start-Sleep -Seconds 1}}
+ CategoryInfo : InvalidOperation: (System.Threading.ThreadStart:ThreadStart) [], RuntimeException
+ FullyQualifiedErrorId : OperatorRequiresNumber
\&quot;

et une autre fois :

\&quot;C:\Users\toto\Documents\Powershell\test_multithread3.ps1 : Index was outside the bounds of the array.
At line:1 char:24
+ .\test_multithread3.ps1 &lt;&lt;&lt;&lt;
+ CategoryInfo : NotSpecified: (:) [test_multithread3.ps1], IndexOutOfRangeException
+ FullyQualifiedErrorId : System.IndexOutOfRangeException,test_multithread3.ps1

\&quot;

C'est probablement due à un problème entre le Host les pipeline et le runtime Powershell.

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.104 secondes
Propulsé par Kunena