Cross thread problème

Résolu
WishhhMaster Messages postés 327 Date d'inscription mardi 17 février 2004 Statut Membre Dernière intervention 10 avril 2010 - 7 févr. 2007 à 12:33
WishhhMaster Messages postés 327 Date d'inscription mardi 17 février 2004 Statut Membre Dernière intervention 10 avril 2010 - 12 févr. 2007 à 06:38
Bonjour,

J'ai un petit problème lié au cross threading.  Dans mon application, l'utilisateur choisit divers fichiers images, dont les miniatures sont ensuite affichées dans une listview.  Le problème, c'est que dans le cas où il y a beaucoup d'images à afficher, cela prend pas mal de temps.  J'utilise donc un bakgroundworker pour mettre les images dans une imagelist (DoWork) , et quand c'est finit j'ajoute les images dans ma listview (RunWorkerCompleted).  Je devrais donc éviter l'erreur "cross thread operation not valid", qui arrive quand un control est modifié par un thread autre que celui qui l'a crée.
Ca marche effectivement la premiere fois, mais la 2e fois qu'on choisit les images à afficher, il y a l'erreur.  Ca me dit que le control lsv_minipcts est modifié par un thread autre que celui qui l'a crée.  Le truc bizarre, c'est que dans le débugger VS, ça pointe sur un endroit où je n'appelle pas lsv_minipcts, mais mon image list.  Je pense que en fait les 2 deviennent "connectés" après avoir ajouter les items dans la listview.

Je ne sais pas si c'est clair, donc voilà un petit bout de code:

// imglst: imagelist
//tabstream : un tableau de stream
//filenames: un tableau de string
// bkgwk_openfiles:  mon backgroundworker
// lsv_minipcts: ma listview

private void bkgwk_openfiles_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i < filenames.Length; i++)
    {
        // on crée un stream pour chaque fichier
                tabstreams[i] = new FileStream(filenames[i], FileMode.Open, FileAccess.Read);
       // on ajoute l'image à la listview à partir du stream
                    imglst.Images.Add(filenames[i], Image.FromStream(tabstreams[i])); // ERREUR ICI
    }  
}

private void bkgwk_openfiles_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
 {
            for (int i = 0; i < filenames.Length; i++)
                    lsv_minipcts.Items.Add(filenames[i], Path.GetFileName(filenames[i]), filenames[i]);
                // on ajoute l'item correspondant à l'image
}

J'espère que c'est plus clair.  Utiliser Invoke ou BeginInvoke n'a pas l'air de marcher non plus. Si quelqu'un a une solution...

Merci :)

4 réponses

WishhhMaster Messages postés 327 Date d'inscription mardi 17 février 2004 Statut Membre Dernière intervention 10 avril 2010 8
12 févr. 2007 à 06:38
J'ai finalement gardé ma solution, mais au lieu de créer directement les miniatures moi-même, je les lis dans les données EXIF des fichiers (pour ceux qui en contienent).  C'est beaucoup plus rapide.
3