Question

J'ai un contrôle PictureBox sur un formulaire qui est supposé dessiner quelque chose toutes les 100 ms.

Le thread d'arrière-plan effectue des calculs dans une boucle et déclenche un événement après chaque itération.

Modifié (en réponse à un commentaire) :

World world = new World();

void CreateBackgroundThread() {
    Thread backgroundThread = new Thread(world.BackgroundWorkerFunction);
    backgroundThread.Start();
}

& nbsp;

public class World { 

    void BackgroundWorkerFunction() {
        IPiece piece = PieceFactory.Create();
        for (int i = 0; i < stepsCount; i++) {
            piece.Calculate();
            if (OnPieceStep != null) {
                OnPieceStep(piece);
            }
        }
    }

}

Dans le formulaire principal, il y a un gestionnaire, défini par:

world.OnPieceStep += DrawScreen;

et le wrapper Invoke (étant donné que le contrôle sur lequel dessiner est créé, est créé dans le thread d'interface utilisateur).

void DrawScreen(IPiece piece) {
    this.Invoke(new PieceStep(_drawScreen), piece);
}
void _drawScreen(IPiece piece) {
    drawer.Draw(world.Board, piece);
}

Maintenant, j'aimerais que la boucle for suspende 100 ms après chaque itération. J'ai donc ajouté Thread.Sleep (100); avant de tirer un événement:

for (int i = 0; i < stepsCount; i++) {
    IPiece piece = Calculate();
    if (OnPieceStep != null) {
        Thread.Sleep(100);
        OnPieceStep(piece);
    }
}

Cependant, cela n’actualise pas la PictureBox toutes les 100 ms, mais ne dessine que la dernière itération de la boucle, et seulement après la fin de la boucle.

Thread.Sleep ne devrait-il pas suspendre le thread sur lequel il est appelé, pas le thread UI? & nbsp; Mise à jour : je viens d'essayer de cliquer sur l'application pendant que le fil d'arrière-plan calcule. Le programme se bloque ("ne répond pas"), donc le Thread.Sleep était évidemment appelé sur UI Thread. Est-ce que ce comportement attendu ou quelque chose ne va pas avec mon threading?

Était-ce utile?

La solution 2

Comme indiqué sur la cette page :

  

Thread.Sleep est unique parmi les   méthodes de blocage qui suspend   Pompage de messages Windows dans un   Application Windows Forms ou COM   environnement sur un fil pour lequel le   modèle d'appartement simple thread est   utilisé. Cela n'a que peu d'importance   avec les applications Windows Forms, en   que toute longue opération de blocage sur   le fil principal de l'interface utilisateur fera la   l'application ne répond pas & # 8211; et est   donc généralement évité & # 8211; indépendamment   du message pompage ou non   est " techniquement " suspendu. le   la situation est plus complexe dans un héritage   Environnement d'hébergement COM, où il peut   parfois être souhaitable de dormir tout   garder le message en vie.   Chris Brumme de Microsoft discute   ceci dans son journal Web (recherche:   'COM "Chris Brumme"'.

Il semble que Thread.Sleep () dans WinForms met toujours l'interface utilisateur en pause, quel que soit le fil appelé.

Autres conseils

De filetage prospective tout va bien. Le problème le plus probable repose sur la méthode _drawScreen (IPiece piece). Avez-vous essayé d'actualiser / mettre à jour la fenêtre après avoir dessiné?

Quelques idées: La méthode Control.Invoke transmet le délégué fourni en tant que paramètre sous forme de message à l’aide de la fonction Win32 SendMessage.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top