J'ai une méthode que j'appelle du thread principal. Cette méthode crée un nouveau thread. Le code ressemble à ceci:"Le thread appelant ne peut pas accéder à cet objet car un thread différent le possède" lors de la mise à jour du contrôle de l'interface utilisateur depuis un thread différent dans WPF
MouseCursorWallObject MouseCursorWall = null;
List<MovingRectangle> MovingRectangles = null;
DrawingImage RenderedImage;
public MainWindow()
{
InitializeComponent();
PrepareObjects();
GameLoopRun();
}
private void GameLoopRun()
{
Thread thread = new Thread(() =>
{
while (true)
{
DateTime dtStart = DateTime.Now;
Events();
Update();
Display();
DateTime dtEnd = DateTime.Now;
TimeSpan ts = dtEnd - dtStart;
if (SkipTicks - ts.TotalMilliseconds >= 0)
{
Thread.Sleep((int)(SkipTicks - ts.TotalMilliseconds));
}
}
});
thread.Start();
}
Dans la méthode Display(), j'essaie de mettre à jour le contrôle Image. « Affichage() » méthode ressemble à ceci:
private void Display()
{
DrawingGroup imageDrawings = new DrawingGroup();
// Drawing main canvas
imageDrawings.Children.Add(DrawingObject(500, 350, 0, 0, new Uri(@"Images\gameCanvas.jpg", UriKind.Relative)));
// Drawing mouse cursor wall
imageDrawings.Children.Add(DrawingObject(MouseCursorWall.Width, MouseCursorWall.Height, MouseCursorWall.GetLocX, MouseCursorWall.GetLocY, MouseCursorWall.DisplayTexture));
for (int i = 0; i < MovingRectangles.Count; i++)
{
MovingRectangle o = MovingRectangles[i];
// Drawing moving object
imageDrawings.Children.Add(DrawingObject(20, 20, o.GetLocX, o.GetLocY, o.TextureUri));
}
if (GamePause == true)
{
}
RenderedImage = new DrawingImage(imageDrawings);
// Image control on main UI thread
renderImage.Dispatcher.Invoke(() =>
{
renderImage.Source = RenderedImage;
});
}
Le problème est quand I'am essayer la mise à jour le contrôle de l'image en utilisant Dispatcher.Invoke I'am erreur de réception « Le thread appelant ne peut pas accéder à cet objet parce qu'un autre thread est propriétaire il". J'ai essayé beaucoup d'options différentes, et une seule fonctionne très bien:
private void Display()
{
this.Dispatcher.Invoke(() => {
DrawingGroup imageDrawings = new DrawingGroup();
// Drawing main canvas
imageDrawings.Children.Add(DrawingObject(500, 350, 0, 0, new Uri(@"Images\gameCanvas.jpg", UriKind.Relative)));
// Drawing mouse cursor wall
imageDrawings.Children.Add(DrawingObject(MouseCursorWall.Width, MouseCursorWall.Height, MouseCursorWall.GetLocX, MouseCursorWall.GetLocY, MouseCursorWall.DisplayTexture));
for (int i = 0; i < MovingRectangles.Count; i++)
{
MovingRectangle o = MovingRectangles[i];
// Drawing moving object
imageDrawings.Children.Add(DrawingObject(20, 20, o.GetLocX, o.GetLocY, o.TextureUri));
}
if (GamePause == true)
{
}
RenderedImage = new DrawingImage(imageDrawings);
renderImage.Source = RenderedImage;
});
}
Pouvez-vous me expliquer pourquoi deuxième option de la méthode « Affichage() » fonctionne très bien, mais le premier lancer exception? Qu'est ce que je fais mal?
J'ai déjà trouvé ce sujet. – Shagohad
Ok, bien, vous pourriez être en mesure de faire fonctionner le premier exemple si vous .Freeze() le DrawingImage d'abord, mais vous devriez probablement le créer sur le thread UI (selon votre deuxième exemple). – Dutts