2016-12-29 43 views
-2

無法啓動,我試圖讓一個線程在下面的未完成的代碼運行。其基礎如下:當控制檯應用程序啓動時,它應該啓動一個將關閉的線程,導航到網頁(最終會進行一些處理),然後停止並關閉單獨的線程。結合起來,主應用程序將只提供一個菜單給用戶,直到應用程序退出。最終,導航線程將被放入一個單獨的方法,使其定期調用每隔一段時間,但是這不應該是有關這個問題,我不認爲......線程在C#控制檯應用程序

我的理解是,單獨的線程應只需在主控制檯應用程序旁邊運行,並在完成其任務時終止,就像控制檯一樣,如果你不阻止它退出????? 它實際上看起來像是它並沒有從第一個地方開始,因爲我沒有通過browser_DocumentCompleted事件觸發的方式得到響應(我知道IP地址是活着的並且是活動的,因爲我已經檢查過了!!)

任何人都可以闡明爲什麼單獨的線程沒有運行,或似乎不是?

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; 
      } 
     } 
    } 
} 
} 

這裏我有一個catch 22的情況。一方面,如果我離開的代碼是上面,什麼後application.run()方法沒有得到執行,這意味着WebBrowserNavigationComplete標誌將永遠不會改變,回調將永遠不會被退回。
然而,如果我以後

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

移動application.run()代碼永遠不會因爲它是停留在while循環等待WebBrowserNavigationComplete標誌,該標誌將永遠不會改變,因爲消息循環是永遠無法達到,以調用application.run()這一點開始!

我不能相信我是第一次做這樣的事?克服這種僵局的正常方法是什麼?

由於

回答

1

WebBrowser是一個WinForms構建體,並需要一個應用程序環路設置來處理消息它。既然你有一個控制檯應用程序,並沒有消息循環,它將無法正常工作。

您需要使用Application.Run(它需要從STA線程運行)顯式創建一個新的應用程序循環才能正常工作。

+0

好的,謝謝你的建議。我已經編輯了上面的代碼,並添加了'Application.Run()'方法,但沒有變化,它仍然和以前一樣。然而,我認爲它是在線程內的錯誤的地方?似乎無法找到許多信息,而不是它在MSDN網站上的內容! – cosmarchy

+0

@cosmarchy'Application.Run'不會返回,直到退出應用程序,你永遠退出應用程序,所以它永遠不會返回,並且永遠不會運行它之後的任何代碼。 – Servy

+0

我不確定我是否理解它在您退出應用程序之前不會返回。我已經編輯我原來的職位,並已改變了'Application.Run'的,這似乎工作的位置,但是我不明白爲什麼.... – cosmarchy