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 :

Méthodes asynchrones et threads


Sujet :

C#

  1. #1
    Membre du Club
    Homme Profil pro
    SUPINFO International University
    Inscrit en
    Novembre 2011
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : SUPINFO International University

    Informations forums :
    Inscription : Novembre 2011
    Messages : 62
    Points : 40
    Points
    40
    Par défaut Méthodes asynchrones et threads
    Bonjour à tous,

    J'ai un programme qui nécessite un chargement de données relativement lourd et qui prends donc un petit temps (environ 2 minutes). Évidemment, durant ce chargement toute mon appli se retrouve bloquée et je ne peux même plus réduire la fenêtre.

    Bref, ce que je voudrai c'est exécuté tout le chargement en fond puis être alerté quand celui-ci est terminé.

    Tout d'abord j'essaie de m'en tenir à débloqué l'appli durant l'exécution de cette tâche. En cherchant un peu partout sur le Web, j'ai mis ce code en place :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Action<object> action = (object obj) =>
                        {
                            Application.Current.Dispatcher.BeginInvoke(new Action(() => { test(); }));
                        };
     
                        Task t1 = new Task(action, "alpha");
                        t1.Start();
    Cela ne fonctionne que partiellement car après avoir démarré la Task t1, la fonction dans laquelle ce code se trouve continue de s'exécuter jusqu'à la fin.

    Cool Sauf qu'ensuite mon application reste tout de même bloquée...

    Merci d'avance pour votre aide

  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 : 47
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 970
    Points : 3 304
    Points
    3 304
    Par défaut
    Bonjour, regarder du coté du BackGroundWorker qui pourrait vous aider. Aller voir dans la section Source c# j'y ai déposé une source comme exemple.
    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
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour
    La tu es dans l'AP Task Paralla du .net framework.....Pas faites pour pour demarrer des taches asynchrones lourdes
    Il est preferable,comme dit par binou, d'utiliser le backgroundworker dans ton cas....
    La parallelisation des taches (taches avec boucles for.parallal et foreach.parallal) est utile quand on a beaucoup de calculs en general et repondant aux conditions de "parallellisation" ou "taches independantes" .Exemple :calcul matriciel......

    Relativement au dispatcher wpf ,il est beaucoup plus utilise pour "atteindre" l'UI user quand on cherche à afficher les donnees de la tache en background sur les controles(resultat).......
    pour ta curiosite voici 2 exemples:

    1er exemple d'un code qui execute un long calcul sans utilisation de task...
    code xaml du winform:
    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
     
    <Window x:Class="WpfApplication1.WinTaskBlocking"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="WinTaskBlocking" Height="300" Width="300">
     
        <StackPanel>
            <DockPanel
                Height="25">
                <Button
                    DockPanel.Dock="Left"
                    x:Name="btnTaskStart"
                    Width="100"
                    Content="Task Start"
                    Click="btnTaskStart_Click">
     
                </Button>
            </DockPanel>
            <DockPanel
                Height="25">
                <TextBlock 
                   DockPanel.Dock="Left"
                    x:Name="tbResult"
                    Foreground="DarkGreen"
                    Background="white" 
                    FontSize="14"
                    Width="200">
                </TextBlock>
     
            </DockPanel>
            <DockPanel
                Height="25">
                <Label 
                    DockPanel.Dock="Bottom"
                    x:Name="lbElapsedTime"
                    Foreground="white"
                    Background="Red"
                    Width="200">
                </Label>
            </DockPanel>
        </StackPanel>
    </Window>
    code behind .cs du winform:
    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
     
    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.Shapes;
    using System.Diagnostics;
    using System.Threading;
     
    namespace WpfApplication1
    {
        /// <summary>
        /// Logique d'interaction pour WinTaskBlocking.xaml
        /// </summary>
        public partial class WinTaskBlocking : Window
        {
            public WinTaskBlocking()
            {
                InitializeComponent();
            }
     
            private void btnTaskStart_Click(object sender, RoutedEventArgs e)
            {
                tbResult.Text = "";
                lbElapsedTime.Content = "";
                var watch = Stopwatch.StartNew();
                int i = 1000;
                var result = BackgroundTask(i);
                this.tbResult.Text += "sum :  " + i.ToString() +
                    " result : " + result.ToString() + Environment.NewLine;
                var time = watch.ElapsedMilliseconds; 
                lbElapsedTime.Content += time.ToString();
            }
     
     
            private static int BackgroundTask(int parameter)
            {
     
                int result = 0;
                for (int i = 0; i <= parameter; i++)
                {
                    result += i;
                    Thread.Sleep(1);
                }
                return result;
            }
        }
    }

    2e exemple d'un code qui execute un long calcul avec un class task...
    code xaml du winform:

    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
     
    <Window x:Class="WpfApplication1.WinTask"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="WinTask" Height="300" Width="300">
        <StackPanel>
            <DockPanel
                Height="25">
                <Button
                    DockPanel.Dock="Left"
                    x:Name="btnTaskStart"
                    Width="100"
                    Content="Task Start"
                    Click="btnTaskStart_Click">
     
                </Button>
                <Button
                    DockPanel.Dock="Right"
                    x:Name="btnStateTask"
                    Width="100"
                    Content="Task State"
                    Click="btnStateTask_Click">
     
                </Button>
            </DockPanel>
            <DockPanel
                Height="25">
                <TextBlock 
                   DockPanel.Dock="Left"
                    x:Name="tbResult"
                    Foreground="DarkGreen"
                    Background="white" 
                    FontSize="14"
                    Width="200">
                </TextBlock>
                <TextBlock 
                    DockPanel.Dock="Right"
                    x:Name="tbStatusTask"
                    Foreground="DarkBlue"
                    Background="white"  
                    Width="200"
                    FontSize="14">
                </TextBlock>
            </DockPanel>
            <DockPanel
                Height="25">
                <Label 
                    DockPanel.Dock="Bottom"
                    x:Name="lbElapsedTime"
                    Width="200"
                    Foreground="white"
                    Background="Red" >
                </Label>
            </DockPanel>
        </StackPanel>
    </Window>
    code behind .cs du winform:
    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
     
    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.Shapes;
    using System.Threading.Tasks;
    using System.Diagnostics;
    using System.Threading;
     
    namespace WpfApplication1
    {
        /// <summary>
        /// Logique d'interaction pour WinTask.xaml
        /// </summary>
        public partial class WinTask : Window
        {
     
            Task myTask;
            public WinTask()
            {
                InitializeComponent();
            }
     
            private void btnTaskStart_Click(object sender, RoutedEventArgs e)
            {
                tbResult.Text = "";
                lbElapsedTime.Content = "";
                var watch = Stopwatch.StartNew();
                int i = 1000;
                List<Task> tasks = new List<Task>();
                myTask = Task.Factory.StartNew(() =>
                {
                    var result = BackgroundTask(i);
                    // ce code sans passer par le dispatcher plantera ...!!!!!!!!!
                     //this.tbResult.Text += "sum :  " + i.ToString() + " result : " +
                     //                        result.ToString() + Environment.NewLine;
                    this.Dispatcher.BeginInvoke(new Action(() =>
                         this.tbResult.Text += "sum :  " + i.ToString() + " result : " +
                                             result.ToString() + Environment.NewLine)
                         , null);
                });
                tasks.Add(myTask);
                //toutes les taches sont terminees.oui?display ElapsedTime...
     
                Task.Factory.ContinueWhenAll(tasks.ToArray(),
                    result =>
                    {
                        var time = watch.ElapsedMilliseconds;
                        this.Dispatcher.BeginInvoke(new Action(() =>
                            lbElapsedTime.Content += time.ToString()));
                    }
                );
     
            }
     
            private void btnStateTask_Click(object sender, RoutedEventArgs e)
            {
                tbStatusTask.Text = "";
                if (myTask != null)
                {
                    this.tbStatusTask.Text = myTask.Id.ToString();
                    this.tbStatusTask.Text = this.tbStatusTask.Text + " ---- " + myTask.Status.ToString();
                }
            }
            public static double SumRootN(int root)
            {
                double result = 0;
                for (int i = 1; i < root; i++)
                {
                    result += Math.Exp(Math.Log(i) / root);
                }
                return result;
            }
            private static int BackgroundTask(int parameter)
            {
     
                int result = 0;
                for (int i = 0; i <= parameter; i++)
                {
                    result += i;
                    //simule une pause.... 
                    Thread.Sleep(1);
                }
                return result;
            }
        }
    }
    bonne soiree...........

  4. #4
    Membre du Club
    Homme Profil pro
    SUPINFO International University
    Inscrit en
    Novembre 2011
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : SUPINFO International University

    Informations forums :
    Inscription : Novembre 2011
    Messages : 62
    Points : 40
    Points
    40
    Par défaut
    Bonjour MABROUKI et binou76,

    Je vous remercie d'abord pour vos conseils et toutes ces explications.

    Je me suis donc tourné du côté du BackgroundWorker, avec succès, enfin presque !

    J'ai réussi à le mettre en place sans trop de soucis. Dans le DoWork j'ai mis un Thread.Sleep(15000), et mon appli n'est pas bloquée.

    Seulement si je mets :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application.Current.Dispatcher.BeginInvoke(new Action(() => { test(); }));
    Là, ça bloque quand même.
    J'imagine que cela vient du Dispatcher. Seulement si je ne le mets pas j'ai une erreur : "Le thread appelant ne peut pas accéder à l'objet parce qu'un autre thread en est propriétaire".

    J'ai donc besoin de ce Dispatcher, et je ne vois pas d'autre solution

  5. #5
    Membre éprouvé Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Points : 1 188
    Points
    1 188
    Par défaut
    Bonjour,

    Dispatcher.BeginInvoke et backgroundworker font la même chose, de l’exécution de tache asynchrone (Pas de polémique sur le fait qu'ils soient conceptuellement différents, je le sais très bien).

    Bref, il faut que tu utilises le backgroundworker et le reportprogress pour mettre à jour ton UI ou appeler d'autres méthodes.

    Bon dév.
    Un âne se croit savant parce qu'on le charge de livres (proverbe américain)

    N'oubliez pas de avant de
    Pas de question techniques par MP, c'est contre la philosophie du forum

  6. #6
    Membre du Club
    Homme Profil pro
    SUPINFO International University
    Inscrit en
    Novembre 2011
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : SUPINFO International University

    Informations forums :
    Inscription : Novembre 2011
    Messages : 62
    Points : 40
    Points
    40
    Par défaut
    Bonjour à tous,

    Le sujet est résolu. J'ai mis tout ce qui est modification de l'UI dans le "ProgressChanged" et à la fin du BackgroundWorker.

    Merci à tous

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 30/10/2013, 13h48
  2. Réponses: 4
    Dernier message: 22/06/2008, 12h00
  3. [C++/CLI] Méthode cyclique dans thread principal
    Par Plio dans le forum C++/CLI
    Réponses: 4
    Dernier message: 09/10/2007, 16h19
  4. [C++/CLI] Méthode cyclique dans thread principal
    Par Plio dans le forum Général Dotnet
    Réponses: 0
    Dernier message: 07/10/2007, 22h02
  5. Méthode de classe "threadée"
    Par Ecco59 dans le forum C++
    Réponses: 13
    Dernier message: 16/01/2007, 15h20

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