2016-12-29 5 views
-2

Ich versuche, einen Thread in den folgenden unvollendeten Code ausgeführt werden. Die Grundlagen davon sind wie folgt; Wenn die Konsolen-App gestartet wird, sollte sie einen Thread starten, der sich ausschaltet, um zu einer Webseite zu navigieren (die eventuell eine Verarbeitung durchführt), bevor sie den separaten Thread stoppt und auslöst. In Verbindung damit stellt die Hauptanwendung dem Benutzer nur ein Menü zur Verfügung, bis die App beendet wird. Schließlich wird der Navigations-Thread in eine separate Methode eingefügt, so dass es regelmäßig aufgerufen wird, aber dies sollte nicht relevant für diese Frage sein, glaube ich nicht ...Thread nicht in der C# -Konsolenanwendung gestartet

Mein Verständnis ist, dass der separate Thread sollte nur neben der Hauptkonsolen-Anwendung laufen und beenden, wenn es seine Aufgabe abgeschlossen hat, genau wie eine Konsole, wenn Sie nicht verhindern, dass es beendet wird ????? Was es tatsächlich aussieht, ist, dass es nicht an erster Stelle beginnt, da ich keine Antwort über die browser_DocumentCompleted Ereignisauslösung bekomme (ich weiß, dass die IP-Adresse aktiv und aktiv ist, wie ich überprüft habe!)

Kann jemand Licht in die Sache bringen, warum der separate Thread nicht läuft oder nicht zu sein scheint?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Windows.Forms; 

namespace ConsoleThreadTest 
{ 
class Program 
{ 
    public delegate void Callback(string Status); 

    static void Main(string[] args) 
    { 

     NavigateToIPAddress GEIPA = new NavigateToIPAddress(new Uri("http://192.168.1.254"), new Callback(ResultCallback)); 
     Thread PerformThreadTask = new Thread(new ThreadStart(GEIPA.PerformThreadTask)); 
     PerformThreadTask.SetApartmentState(ApartmentState.STA); 
     PerformThreadTask.Start(); 

     Console.WriteLine("{0}","Press escape key to exit"); 

     while (true) 
     { 
      if (Console.KeyAvailable) 
      { 
       ConsoleKeyInfo key = Console.ReadKey(true); 
       switch (key.Key) 
       { 
        case ConsoleKey.Escape: 
         //Kill off thread if it is still running. 
         if (PerformThreadTask.ThreadState == ThreadState.Running) 
         { 
          PerformThreadTask.Abort(); 
         } 
         Environment.Exit(0); 
         break; 
        default: 
         break; 
       } 
      } 
     } 

    } 

    public static void ResultCallback(string Status) 
    { 
     Console.WriteLine("{0}\t{1}", DateTime.Now.ToString("h:mm:ss"), Status); 
    } 

    public class NavigateToIPAddress 
    { 
     private Uri WebAddress; 
     private bool WebBrowserNavigationComplete = false; 

     // Delegate used to execute the callback method when the task is complete. 
     private Callback callback; 

     // The constructor obtains the state information and the callback delegate. 
     public NavigateToIPAddress(Uri IPAddressToNavigateTo, Callback callbackDelegate) 
     { 
      WebAddress = IPAddressToNavigateTo; 
      callback = callbackDelegate; 
     } 

     // The thread procedure performs the task and then invokes the callback delegate with the status. 
     public void PerformThreadTask() 
     { 
      var br = new WebBrowser(); 
      br.DocumentCompleted += browser_DocumentCompleted; 
      try 
      { 
       br.Navigate(WebAddress); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("{0}\tSome error occurred: {1}", DateTime.Now.ToString("h:mm:ss"), e.Message); 
      } 

      Application.Run(); 

      while (WebBrowserNavigationComplete == false) 
      { 
      } 

      if (callback != null) 
       callback("Summit occurred"); 
     } 

     private void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
     { 
      var br = sender as WebBrowser; 
      if (br.Url == e.Url) 
      { 
       Console.WriteLine("{0}\tNavigated to {1}", DateTime.Now.ToString("h:mm:ss"), e.Url); 
       WebBrowserNavigationComplete = true; 
      } 
     } 
    } 
} 
} 

Hier habe ich eine Fang 22 Situation. Auf der einen Seite, wenn ich den Code wie oben beschrieben belasse, wird alles nach der application.run() Methode nicht ausgeführt, was bedeutet, dass sich das WebBrowserNavigationComplete Flag niemals ändert und der Callback nie zurückgegeben wird.
Wenn aber ich application.run() nach

if (callback != null) 
    callback("Summit occurred"); 

der Code bewegen wird nie diesen Punkt erreichen, um application.run() zu nennen, wie es in der while-Schleife steckt für die WebBrowserNavigationComplete Flagge warten, die nie als die Nachrichtenschleife ist nie ändern gestartet!!

Ich kann nicht glauben, dass ich der Erste bin, der so etwas macht? Was ist der normale Weg, um diese Sackgasse zu überwinden?

Dank

Antwort

1

WebBrowser ist ein winforms konstruieren und erfordert eine Anwendung Schleifennachrichten für sie verarbeiten eingerichtet werden. Da Sie eine Konsolenanwendung und keine Nachrichtenschleife haben, funktioniert es nicht richtig.

Sie müssen explizit eine neue Anwendungsschleife mit Application.Run erstellen (die aus einem STA-Thread ausgeführt werden muss), damit es funktioniert.

+0

ok, danke für den Vorschlag. Ich habe den obigen Code bearbeitet und die 'Application.Run()' Methode hinzugefügt, aber es gibt keine Änderung und es funktioniert immer noch genauso wie zuvor. Ich denke aber, dass es an der falschen Stelle innerhalb des Threads ist ??? Ich kann nicht herausfinden, was es auf der MSDN-Website gibt. – cosmarchy

+0

@cosmarchie 'Application.Run' kehrt erst zurück, wenn Sie die Anwendung beenden und Sie die Anwendung nie beenden, so dass sie nie mehr zurückkehrt und keinen der folgenden Code ausführt. – Servy

+0

Ich bin mir nicht sicher, ob ich weiß, dass es erst nach dem Beenden der Anwendung zurückgegeben wird. Ich habe meinen ursprünglichen Beitrag bearbeitet und habe den Speicherort der 'Application.Run' geändert, die zu funktionieren scheint, aber ich verstehe nicht warum .... – cosmarchy

Verwandte Themen