Bonsoir a tous,
Je sollicite de moins en moins le forum (grâce vous) mais cette fois-ci je suis a nouveau bloqué sur un problème un peu épineux pour moi.
J'ai un code qui fonctionne mais qui m’empêche aujourd'hui d'implémenter correctement l'annulation des Process et je souhaite également supprimer les BackGroundWorker car normalement je ne devrais pas en avoir besoin avec des objets Process.
Mon problème se situe plus au niveau de l’écriture de la structure du code, je ne sais pas comment m'y prendre en évitant de tout casser et compte tenu des différents points bloquant (listés plus bas) que je pourrais rencontrer. Votre suggestions me seront vraiment d'une aide très précieuse.
Pour commencer voici mon code simplifié au maximum : (j'ai pris l'exemple de 2 processus d'encodage vidéo avec ffmpeg qui correspondent a un encodage en 2 passes).
La procédure d’exécution des processus :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 Private Sub BackGroundWorkerFFMPEG_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) ConvertWithFFmpeg(TSFile) End Sub Private Sub ConvertWithFFmpeg(InputFilename As String) .... ' Ceci est un grand bloc de code ou je prépare les lignes de commandes entre autres. Dim FFMPEG_EXE as string = "ffmpeg.exe" Dim CommandeLine as string = "Ma ligne de commande1" Call ShellExecuteFFMPEG(FFMPEG_EXE, CommandeLine) .... CommandeLine = "Ma ligne de commande2" Call ShellExecuteFFMPEG(FFMPEG_EXE, CommandeLine) .... End Sub
Les points et problèmes identifiés :
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 Private Sub ShellExecuteFFMPEG(ByVal ExeFile As String, CommandLine As String) Dim MonProcess As New Process AddHandler MonProcess.OutputDataReceived, AddressOf OutputDataReceived AddHandler MonProcess.ErrorDataReceived, AddressOf ErrorDataReceived AddHandler MonProcess.Exited, AddressOf ProcessExit MonProcess.EnableRaisingEvents = True MonProcess.StartInfo.FileName = ExeFile MonProcess.StartInfo.Arguments = CommandLine MonProcess.StartInfo.CreateNoWindow = True MonProcess.StartInfo.UseShellExecute = False MonProcess.StartInfo.RedirectStandardOutput = True MonProcess.StartInfo.RedirectStandardInput = True MonProcess.StartInfo.RedirectStandardError = True MonProcess.Start() MonProcess.BeginOutputReadLine() MonProcess.BeginErrorReadLine() MonProcess.WaitForExit() MonProcess.Close() End Sub Private Sub OutputDataReceived(sender As Object, e As System.Diagnostics.DataReceivedEventArgs) If e.Data = Nothing Then Exit Sub frmProgress1.SetProgress(e.Data.ToString, True, frmProgress.ProcessNames.FFmpeg) End Sub Private Sub ErrorDataReceived(sender As Object, e As System.Diagnostics.DataReceivedEventArgs) If e.Data = Nothing Then Exit Sub frmProgress1.SetProgress(e.Data.ToString, True, frmProgress.ProcessNames.FFmpeg) End Sub Private Sub ProcessExit(sender As Object, e As System.EventArgs) My.Computer.Audio.Play(My.Resources.misc229, Microsoft.VisualBasic.AudioPlayMode.Background) ' Son joué a chaque fin de processus End Sub
1- Pour commencer je crois que l'instanciation des objets Process dans la procédure ShellExecuteFFmpeg est une mauvaise idée, car je ne peux pas accéder à cet objet en dehors de la procédure et a fortiori pour annuler depuis mon formulaire d'affichage de la progression a l'aide de MonProcess.kill ou MonProcess.CloseMainWindow.
Est ce que vous pensez que le mieux serait d'utiliser 2 objets Process ou un seul ? et ou ? (dans le Form.Load par exemple) ? Comment réecrire ShellExecute dans ce cas ?
2- Mes Processus se lance dans un backgroundWorker, je dois supprimer ce dernier. A priori cela ne devrait pas me poser trop de problème sauf que j'avais fait cela pour libérer le Thread qui exécute l'affichage de la progression (d’après un post de Pol63 (hier) je devrais utiliser l’événement exited, je n'ai pas bien compris comment cet événement pourrait me permettre d’éviter le freeze puisque celui-ci ne s’exécute qu'une fois que le Processus est terminé (si je pouvais avoir une explication la dessus ça serait sympa).
(Pour information mon formulaire frmProgress1 me sert pour l'affichage de la progression fournie pas les DataReceived. Ce formulaire est instancié depuis le Thread UI et ma méthode SetProgress utilise une invocation pour permettre l'affichage Cross-Threads).
3- J'utilise WaitForExit car le 2eme Processus (2eme passe) doit attendre le 1er Processus pour pouvoir s'exécuter. Mais si je supprime le BackGroundWorker cela signifie que le thread UI va s'arretter sur la ligne WaitForExit et donc figer l'affichage. Comment obtenir un affichage dans ces conditions ?
Je suis conscient de ne pas forcement être très clair dans ma demande mais j'aimerais beaucoup avoir votre aide pour éviter de faire des bêtises et si vous pouvez.
Merci beaucoup.
Partager