2014-01-08 210 views
0

當程序在此控制檯中寫入內容時,是否可以在控制檯中寫入某些內容?當您重命名,刪除某些文件,執行重複操作時,以及程序在控制檯中寫入很多內容時,這會很有用。然後,當程序繼續在控制檯中寫入時,您將能夠編寫一條命令來停止執行重複動作。我認爲這不是很清楚,我用最合適的代碼向你說明了這一事實(但我確切地說它不起作用;))。我們有3個班。程序在此控制檯中寫入時在控制檯中寫入

主類:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     private static bool m_Write; 

     public static bool write 
     { 
      get { return m_Write; } 
      set { m_Write = value; } 
     } 

     static void Main(string[] args) 
     { 
      int index = 0; 

      Console.ReadLine(); 

      m_Write = true; 

      Reader reader = new Reader(); 

      while (m_Write) 
      { 
       index++; 

       Writer writer = new Writer(index.ToString()); 
      } 

     } 
    } 
} 

閱讀課:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Threading; 

namespace ConsoleApplication1 
{ 
    class Reader 
    { 
     private Thread m_Reading_Thread; 
     private string m_text_To_Read; 

     public Reader() 
     { 
      m_Reading_Thread = new Thread(new ThreadStart(Read)); 
      m_Reading_Thread.Start(); 
     } 

     public void Read() 
     { 
      m_text_To_Read = Console.ReadLine(); 

      if (m_text_To_Read == "Stop") 
      { 
       Program.write = false; 
      } 
     } 
    } 
} 

,寫的類:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Threading; 

namespace ConsoleApplication1 
{ 
    class Writer 
    { 
     private Thread m_Writing_Thread; 
     private string m_Text_To_Write; 

     public Writer(string text_To_Write) 
     { 
      m_Text_To_Write = text_To_Write; 

      m_Writing_Thread = new Thread(new ThreadStart(Write)); 
      m_Writing_Thread.Start(); 
     } 

     public void Write() 
     { 
      Console.WriteLine(m_Text_To_Write); 
     } 
    } 
} 

回答

1

像這樣的工作:

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

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var w = new Writer(); 
      var r = new Reader(); 

      while (!r.finish) 
      { 
       w.enabled = true; 
       string k = Console.ReadKey(false).KeyChar.ToString(); 
       w.enabled = false; 

       string line = k + Console.ReadLine(); 
       r.Read(line); 
      } 
     } 
    } 

    class Writer 
    { 
     public bool enabled = true; 

     public Writer() 
     { 
      var timer = new System.Timers.Timer(1000); 
      timer.Elapsed += (a, b) => 
      { 
       if(enabled) 
        Console.WriteLine("Test"); 
      }; 
      timer.Start(); 
     } 
    } 

    class Reader 
    { 
     public bool finish = false; 

     public void Read(string line) 
     { 
      if (line == "stop") 
      { 
       finish = true; 
      } 
     } 
    } 
} 

如果Writer寫入的內容超出了輸入內容,Console.ReadLine()僅考慮您輸入的內容,不要擔心。

+0

哇!有用 !非常感謝 !唯一的「問題」是程序寫的這個詞可以放在你正在編寫的工作中。你是否認爲有一種方法可以避免寫作者在上面輸入的內容上面寫? – Veriditas

+1

我已經編輯在Writer類上創建一個防止寫入控制檯的標誌。該標誌在按鍵時激活,並在完成該行並按下「Enter」時釋放 – LcSalazar

+1

再次編輯...現在它保存按下的觸發該標誌的按鍵。 – LcSalazar

0

在控制檯應用程序的情況下,沒有兩個線程可以在同一時間將數據寫入屏幕。在上面的答案中,Writes()的構造函數不斷執行,直到它結束運行。然後控件將被傳遞給Reader()。所以我認爲這不符合你的需要。糾正我,如果我錯了。

2

這並不像您想要的那樣複雜。通常有兩種方法可以做到這一點。您可以啓動後臺線程來完成寫入操作,並在控制檯上等待讀取的主線程塊,或者您可以讓主線程寫入並讓後臺線程完成讀取操作。我最喜歡的第一個解決方案:

public class Program 
{ 
    private static readonly ManualResetEvent StopWriting = new ManualResetEvent(false); 

    private static void Main(string[] args) 
    { 
     Thread t = new Thread(WriterFunc); 
     t.Start(); 

     string input; 
     do 
     { 
      input = Console.ReadLine(); 
     } while (input != "stop"); 

     // Tell the thread to stop writing 
     StopWriting.Set(); 

     // And wait for the thread to exit 
     t.Join(); 
    } 

    private static void WriterFunc() 
    { 
     int index = 0; 
     while (!StopWriting.WaitOne(Timeout.Infinite)) 
     { 
      ++index; 
      Console.WriteLine(index.ToString()); 
     } 
    } 
} 

請注意,我用了一個ManualResetEvent這裏,而不是Boolean標誌。更好的解決方案是使用CancellationToken。使用標誌會導致各種有趣的問題,因爲編譯器可能會確定該變量不能更改(它假定爲單線程訪問)。即使變量發生變化,您的線程仍可能繼續運行。

如果你想在主線程來執行寫入操作,而後臺線程做閱讀:

public class Program 
{ 
    private static readonly ManualResetEvent StopWriting = new ManualResetEvent(false); 

    private static void Main(string[] args) 
    { 
     Thread t = new Thread(ReaderFunc); 
     t.Start(); 

     int index = 0; 
     while (!StopWriting.WaitOne(Timeout.Infinite)) 
     { 
      ++index; 
      Console.WriteLine(index.ToString()); 
     } 

     // Wait for the background thread to exit 
     t.Join(); 
    } 

    private static void ReaderFunc() 
    { 
     string input; 
     do 
     { 
      input = Console.ReadLine(); 
     } while (input != "stop"); 

     // Tell the main thread to stop writing 
     StopWriting.Set(); 
    } 
} 
+0

謝謝你的提議。我選擇了其他解決方案,但有不同的代碼可能性很有趣! :) – Veriditas