2012-06-27 7 views
3

Je déclarai un champ:thread ne peut pas accéder à l'objet

WriteableBitmap colorBitmap; 

Ensuite, je crée un fil simple qui fait quelque chose:

private void doSomething() 
{ 
    // ... bla bla bla 
    colorBitmap = new WriteableBitmap(/* parameters */); 
    myImage.Source = colorBitmap; // error here:S 
} 

En cas Windows_Loaded je déclarais et a commencé un nouveau thread:

private void window_Loaded(object sender, RoutedEventArgs e) 
{ 
    Thread th = new Thread(new ThreadStart(doSomething)); 
    th.Start(); 
} 

Le problème est que je ne pouvais pas changer la source de myImage. J'ai une erreur comme:

InvalidOperationException était unhandled Le thread appelant ne peut pas accéder à cet objet parce qu'un autre thread est propriétaire.

J'ai essayé d'utiliser Dispatcher.Invoke, mais il n'a pas aidé ...

Application.Current.Dispatcher.Invoke((Action)delegate 
{ 
    myImage.Source = colorBitmap; 
}); 

Je cherchais des réponses, mais jamais trouvé le cas exactement comme le mien. Pourriez-vous m'aider à comprendre comment résoudre des problèmes comme celui-ci (j'ai eu le même problème récemment, mais je ne pouvais pas appeler la méthode, car un autre thread le possédait).

+2

Eh bien, du haut de ma tête, je suppose que cela est WPF ou Silverlight? Si je me souviens bien (ce que je fais rarement!), Vous ne pouvez pas instancier un nouveau 'WriteableBitmap' sur un thread d'arrière-plan (pour une raison stupide). Je ne sais pas pourquoi cela ne fonctionnerait pas après l'avoir envoyé au fil principal. Peut-être essayer 'myImage.Dispatcher.Invoke' au lieu de' Application.Current.Displatcher.Invoke'? –

+0

Voir http://stackoverflow.com/questions/1855308/asynchronous-operations-on-writeablebitmap par exemple. C'est un cas particulier - si vous voyez la documentation http://msdn.microsoft.com/fr-fr/library/system.windows.media.imaging.writeablebitmap.aspx, alors l'explication est 'Quand les mises à jour sont envoyées au thread de rendu , le thread de rendu copie les rectangles modifiés du tampon arrière dans le tampon avant. Le système de rendu contrôle cet échange pour éviter les interblocages et redessiner les artefacts, tels que «déchirer». – dash

+0

myImage.Dispatcher.Invoke - même erreur – Nickon

Répondre

8

Il y a deux problèmes avec votre code:

  1. Vous ne pouvez pas accéder au WriteableBitmap d'un autre thread qui est différent de celui qui l'a créé. Si vous voulez faire cela, vous devez geler votre bitmap en appelant WriteableBitmap.Freeze() d'abord

  2. Vous ne pouvez pas accéder à myImage.Source dans un thread qui n'est pas le thread Dispatcher.

Cela devrait fixer à la fois de ces deux problèmes:

private void doSomething() 
{ 
    // ... bla bla bla 
    colorBitmap = new WriteableBitmap(/* parameters */); 
    colorBitmap.Freeze(); 
    Application.Current.Dispatcher.Invoke((Action)delegate 
    { 
     myImage.Source = colorBitmap; 
    }); 
} 

EDIT Notez que cette approche vous permet de créer et mettre à jour votre bitmap où vous voulez dans votre fil. Une fois que le bitmap est gelé, il ne peut plus être modifié, auquel cas vous devriez juste le jeter et en créer un nouveau.

Sur une note de côté, si vous souhaitez ne pas bloquer votre fil de mise à jour myImage.Source utilisation BeginInvoke au lieu de Invoke

+0

Ok, cela a fonctionné.Il n'y a pas d'erreur maintenant. Mais comment éditer colorBitmap quand il est gelé? Comment le libérer? – Nickon

+0

Glad cela a fonctionné, quant à votre question, s'il vous plaît voir mon edit – GETah

+0

+1 pour une bonne analyse – MBen

Questions connexes