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 :

Problème d'accès à un objet à partir d'un thread [Débutant]


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    ILP
    ILP est déconnecté
    Membre éclairé
    Avatar de ILP
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Mai 2002
    Messages
    260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 260
    Par défaut Problème d'accès à un objet à partir d'un thread
    Bonjour,
    Je débute avec les threads en C#. Et lorsque je tente d’accéder à un objet de mon programme principal après avoir passé sa référence à mon thread. J'ai le message suivant :
    L'exception InvalidOperationException n'a pas été gérée
    Le thread appelant ne peut pas accéder à cet objet parce qu'un autre thread en est propriétaire.
    Voici mon code d'appel dans la classe principale :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        ThreadTest threadTest = new ThreadTest(ref progressBar1);
     
        Thread t = new Thread(new ThreadStart(threadTest.TreadProc));
     
        t.Start();
    }
    Et voici le code de mon thread :
    Code C# : 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
    public class ThreadTest
    {
        private ProgressBar BarreProgression;
     
        public ThreadTest(ref ProgressBar BarreTransfert)
        {
            BarreProgression = BarreTransfert;
        }
     
        public void TreadProc()
        {
            for (int i = 0; i <= 100; i++)
            {
                BarreProgression.Value = i;
                Thread.Sleep(1000);
            }
        }
    }
    Est-ce que quelqu'un sait pourquoi ça ne marche pas ? Peut-être que je m'y prend vraiment comme un manche…

  2. #2
    Membre Expert


    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 970
    Par défaut
    Lorsque vous travailler avec les threads, vous ne pouvez pas avoir accès à un objet ou contrôle appartement à une autre chasse que celle du thread.

    Après quelques recherches sur le net je vois qu'il est conseillé d'utiliser un DispatcherTimer, tu peux commencer à creuser par la.

    Maintenant si cela peut t'aider je viens justement de mettre à disposition un petit programme d'exemple qui pourrait répondre en partie à tes besoins en exécutant le BackGroudWorker qui à mon idée me semble plus simple pour la gestion des threads.

    De plus su je comprend un minimum ton code le but est de faire avancer une ProgressBar qui est justement l'utiliter de mon programme (WPF)

    Je te mets si dessous les 2 fichiers codes si cela peut te dépanner.

    Coté XAML :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <Window x:Class="TestBackgroundWorker.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <ProgressBar Height="28" HorizontalAlignment="Left" Margin="12,97,0,0" Name="Progress" VerticalAlignment="Top" Width="480" />
            <Button Content="Start" Height="23" HorizontalAlignment="Left" Margin="12,131,0,0" Name="btnStart" VerticalAlignment="Top" Width="75" Click="btnStart_Click" />
            <Button Content="End" Height="23" HorizontalAlignment="Left" Margin="93,131,0,0" Name="btnEnd" VerticalAlignment="Top" Width="75" Click="btnEnd_Click" />
            <Label Content="Label" Height="32" HorizontalAlignment="Right" Margin="0,132,11,0" Name="lblAvancement" VerticalAlignment="Top" Width="133" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" />
        </Grid>
    </Window>
    Code Behind :

    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel; 
    namespace TestBackgroundWorker
    {
        /// <summary>
        /// Logique d'interaction pour MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            private BackgroundWorker worker;
            int nMaxValue = 1000;
     
            /* MainWindow
             * 
             * Initialisation de la fenêtre
             */
            public MainWindow()
            {
                InitializeComponent();
     
                // Création du BackgroundWorker
                worker = new BackgroundWorker();
     
                // Indique la fonction de traitement lors du déclenchement de l'événement DoWork
                worker.DoWork += new DoWorkEventHandler(Traitement);
                // Indique la fonction de traitement lors du déclenchement de l'événement indiquant un changement de progression
                worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
                // Indique au BackgroundWorker qu'il peut etre interrompu 
                worker.WorkerSupportsCancellation = true;
                // Indique au BackgroundWorker qu'il doit traiter l'événement de progression
                worker.WorkerReportsProgress = true;
                // Indique la fonction exécutée à la fin du traitement 
                worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
     
                // Initialisation de la progressbar
                Progress.Minimum = 0;
                Progress.Maximum = nMaxValue;
                Progress.Value = 0;
     
                btnEnd.IsEnabled = false; 
            }
     
            // Fonction appelée lors du changement de la progression du traitement 
            private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                // Mise à jour de la progress bar
                Progress.Value = e.ProgressPercentage;
     
                // et du label
                lblAvancement.Content = e.ProgressPercentage.ToString() + " / " + Progress.Maximum;
            }
     
            // Fonction de traitement 
            private void Traitement(object data, DoWorkEventArgs e)
            {
                // On vérifie si la fin du traitement a été demandée
                int i = 0;
                while (!worker.CancellationPending && i < int.Parse(e.Argument.ToString()))
                {
                    System.Threading.Thread.Sleep(100);
     
                    i++;
     
                    // Indique au BackgroundWorker qu'il y a eu progression avec le pourcentage en paramètre
                    worker.ReportProgress(i);
                }
     
                // A la fin du traitement on peut renvoyer un résultat via la propriété result de l'objet DoWorkEventArgs
                e.Result = "J'ai fini";
            }
     
            // Fonction exécutée lorsque l'événement de fin de traitement est déclenchée
            void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                // L'objet RunWorkerCompletedEventArgs peut renvoyer une propriété (Error) contenant une information en cas d'erreur
                if (e.Error != null)
                {
                    MessageBox.Show(e.Error.ToString());
                }
                else
                {
                    // Ou un résultat via la propriété Result
                    MessageBox.Show("Fin du traitement : " + e.Result);
                }
            }
     
            // Bouton Start, lance le BackgroundWorker
            private void btnStart_Click(object sender, RoutedEventArgs e)
            {
                // nMaxValue est un argument pour la fonction de traitement
                worker.RunWorkerAsync(nMaxValue);
                btnStart.IsEnabled = false;
                btnEnd.IsEnabled = true;
            }
     
            // Bouton pour annuler le traitement
            private void btnEnd_Click(object sender, RoutedEventArgs e)
            {
                worker.CancelAsync();
                btnStart.IsEnabled = true;
                btnEnd.IsEnabled = false;
            }
        }
    }Label" Height="32" HorizontalAlignment="Right" Margin="0,132,11,0" Name="lblAvancement" VerticalAlignment="Top" Width="133" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" />
        </Grid>
    </Window>
    Articles sur les technologies .NET

    Une réponse vous a aidé ? utilisez le bouton

    Votre problème est résolu ? utilisez le bouton

  3. #3
    Membre émérite
    Avatar de neilbgr
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2004
    Messages
    651
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 651
    Par défaut
    "Il est interdit par la loi" d'accéder à un objet graphique depuis un thread autre que le thread principal.
    Ainsi, dans ton cas, très classique, d'une indication de progression, tu peux t'orienter vers le BackgroundWorker.

  4. #4
    ILP
    ILP est déconnecté
    Membre éclairé
    Avatar de ILP
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Mai 2002
    Messages
    260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 260
    Par défaut
    Merci pour votre aide .
    En effet, ça marche beaucoup mieux avec un BackgroundWorker. Même si à l’intérieur du DoWork je n'ai toujours pas accès aux objets graphiques du thread principal . Je suis obligé de passer par le ProgressChanged.
    Encore merci pour votre aide .

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 23/03/2012, 15h41
  2. Accès à un objet à partir du nom de son parent
    Par SPKlls dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 22/04/2008, 14h45
  3. Réponses: 2
    Dernier message: 13/04/2007, 12h34
  4. Problème d'accès à un objet!
    Par chrono23 dans le forum C++
    Réponses: 21
    Dernier message: 26/06/2006, 20h21
  5. problème d'accèes à firebird sà partir d'un client
    Par vbcasimir dans le forum Connexion aux bases de données
    Réponses: 2
    Dernier message: 10/05/2005, 08h36

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