Thread per Tastendruck unterbrechen



  • Guten Abend,

    ich habe ein kleines Problem beim Überwachen eines Threads. Ich möchte diesen per Tastendruck unterbrechen.
    Ich habe dazu im Hauptthread eine while-Schleife geschrieben, die mir auf Tastendruck reagiert und den Thread unterbricht. Das klappt auch soweit. Jetzt habe ich aber das Problem wenn mein Thread ordnungsgemäß endet, komme ich nicht mehr aus der while-Schleife raus.

    Wie kann ich von meinem Hauptprogramm einen erzeugten Thread auf Tastendruck unterbrechen? Das ganze soll innerhalb eines Konsolenfenster ablaufen, weil der Thread dort Zwischenergebnisse auflistet.

    Gruß
    physici



  • Was spräche dagegen die Schleife nach dem Aufruf "beende Dich" mit einem break; o.Ä. zu verlassen ?

    Wie startest Du denn den Thread ? Läuft es in einer Winform ab ? Wie schaut die Whileschleife aus ?



  • Also es ist eine Windows Forms Anwendung.

    Thread^ oThread = gcnew Thread( gcnew ThreadStart( &Mathematics::DoLevenberg ) );
    oThread->Priority = Threading::ThreadPriority::Lowest;
    AllocConsole();
    ConsoleKeyInfo cki;
    oThread->Start();
    Thread::Sleep(0);
    while(true)
    {
       cki = Console::ReadKey(true);
       if(cki.Key == ConsoleKey::Escape)
       {
         oThread->Suspend();
         Console::WriteLine(  "Main thread: ThreadProc has supended.  Do you really want to abort it?" );
         Console::WriteLine( "Press ESCAPE to abort, else will resume!" );
         cki = Console::ReadKey(true);
         if(cki.Key == ConsoleKey::Escape)
         {
           oThread->Resume();
           oThread->Abort();
           break;
         }
         else
           oThread->Resume();
       }
    }
    Console::WriteLine("Done");
    FreeConsole();
    

    Wenn ich den Thread mit ESCAPE abbreche, komme ich aus der Schleife ja über das Break raus. Endet der Thread jedoch ordnungsgemäß, so hänge ich weiterhin in der Schleife. Ein Join-Aufruf habe ich schon ausprobiert. Wenn ich den in die Schleife mit hineinpacke, dann läuft er diese nur einmal durch und wartet dann auf das Ende des anderen Threads.



  • Ich habe jetzt das Problem für das Hängen in der While-Schleife gefunden:

    cki = Console::ReadKey(true);
    

    An dieser Stelle steht die Schleife, solange bis eine Eingabe erfolgt. Wenn keine Taste gedrückt wird und der andere Thread zwischenzeitlich endet, dann hängt das Programm halt.

    Gibt es eine andere Möglichkeit, auf einen Tastendruck zu warten, während der andere Thread läuft?



  • klassisch sieht sowas vom konstrukt her folgendermaßen aus

    bool running;
    //...
    void run()
    {
      running = true;
      while(running)
      {
        // do stuff
      }
    }
    // ...
    void stop()
    {
      running = false;
    }
    

    die stop methode wird dann von anderer stelle gerufen. z.b. aus einem zweiten thread, der usereingaben pollt.



  • Ich habs hinbekommen!! 😃 🤡
    Nachdem ich gelesen habe, dass die Funktion

    Console::ReadKey(true)
    

    den aktuellen Thread blockiert, bis ein Eingabe erfolgt ist, habe ich eine andere Funktion zur Überwachung der Tastatureingabe eingesetzt. Diese Funktion ist

    Console::KeyAvailable
    

    Diese schaut in der Nachrichtenschleife, ob sich ein Keypress eingefunden hat oder nicht und gibt das sofort (!) zurück. Damit ist der Thread nicht mehr blockiert.
    Hier daher mal die komplette Lösung:

    Thread^ oThread = gcnew Thread( gcnew ThreadStart( &Mathematics::DoLevenberg ) );
    				 oThread->Priority = Threading::ThreadPriority::Lowest;
    				 ConsoleKeyInfo cki;
    				 oThread->Start();
    				 AllocConsole();
    				 Thread::Sleep(0);
    				 while(oThread->IsAlive)
    				 {
    					 if(Console::KeyAvailable)
    					 {
    						 oThread->Suspend();
    						 cki = Console::ReadKey(true);
    						 Console::WriteLine(  "Main thread: ThreadProc has supended.  Do you really want to abort it?" );
    						 Console::WriteLine( "Press ESCAPE to abort, else will resume!" );
    						 cki = Console::ReadKey(true);
    						 if(cki.Key == ConsoleKey::Escape)
    						 {
    							 oThread->Resume();
    							 oThread->Abort();
    							 break;
    						 }
    						 else
    							 oThread->Resume();
    					 }
    					 Thread::Sleep(1000);
    				 }
    				 oThread->Join();
    				 Console::WriteLine("Fertsch");
    

    Besten Dank euch
    Gruß
    physici


Anmelden zum Antworten