2016-12-29 77 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