2013-01-07 13 views
1

我已經創建了控制檯應用程序。我想讓標籤(在表單上)顯示我在控制檯中鍵入的內容,但是當我運行表單時控制檯會掛起。當窗體顯示時控制檯應用程序不接受輸入

代碼:

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

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     Label a; 
     static void Main(string[] args) 
     { 
      Form abc = new Form(); 
      Label a = new Label(); 
      a.Text = "nothing"; 
      abc.Controls.Add(a); 
      Application.Run(abc); 
      System.Threading.Thread t=new System.Threading.Thread(Program.lol); 
      t.Start(); 


     } 
     public static void lol() 
     { 
      Program p = new Program(); 
      string s = Console.ReadLine(); 
      p.a.Text = s; 
      lol(); 
     } 


    } 
} 

回答

3

Application.Run將阻塞,直到形式已經關閉。所以你應該撥打在一個單獨的線程。

但是,您的用戶界面將被上單獨的線程執行 - 調用Console.ReadLine()之後,你一定不能「碰」從非UI線程的線程上的UI元素,因此,你需要使用Control.InvokeControl.BeginInvoke在UI中進行更改。

此外,您目前正在聲明一個本地變量,名爲a,但從未將值分配給Program.a

下面是一個完整的版本,其中的工作原理:

using System; 
using System.Threading; 
using System.Windows.Forms; 

class Program 
{ 
    private Program() 
    { 
     // Actual form is created in Start... 
    } 

    private void StartAndLoop() 
    { 
     Label label = new Label { Text = "Nothing" }; 
     Form form = new Form { Controls = { label } }; 
     new Thread(() => Application.Run(form)).Start(); 
     // TODO: We have a race condition here, as if we 
     // read a line before the form has been fully realized, 
     // we could have problems... 

     while (true) 
     { 
      string line = Console.ReadLine(); 
      Action updateText =() => label.Text = line; 
      label.Invoke(updateText); 
     } 
    } 

    static void Main(string[] args) 
    { 
     new Program().StartAndLoop(); 
    } 
} 
+0

謝謝你,這工作得很好:) –

2

創建新Thread之前,您正在產卵的形式。這意味着您的程序從未實際創建新的Thread,直到退出Form

您需要使用

System.Threading.Thread t = new System.Threading.Thread(Program.lol); 
t.Start(); 
Application.Run(abc); 
3

有在你的代碼中的許多問題,我將不包括命名的選擇。

  • Application.Run正在阻塞。在你的Form關閉之前,你的其他代碼不會被調用。

  • 你遞歸調用lol(),我不會建議它。改爲使用while循環。

  • 您正嘗試從與創建控件的線程不同的線程設置Label的文本。您需要使用Invoke或類似的方法。

這裏是你的代碼怎麼可能是一個完整的例子。我試圖儘可能少地修改。

class Program 
{ 
    static Label a; 

    static void Main(string[] args) 
    { 
     var t = new Thread(ExecuteForm); 
     t.Start(); 
     lol(); 
    } 

    static void lol() 
    { 
     var s = Console.ReadLine(); 
     a.Invoke(new Action(() => a.Text = s)); 
     lol(); 
    } 

    public static void ExecuteForm() 
    { 
     var abc = new Form(); 
     a = new Label(); 
     a.Text = "nothing"; 
     abc.Controls.Add(a); 
     Application.Run(abc); 
    } 
} 
相關問題