2014-11-04 133 views
0

我有一個控制檯應用程序,它從Console.OpenStandardInput()讀取消息; 我正在做這個任務。但它似乎不起作用。Task.Factory.StartNew無法在控制檯c#應用程序中工作

static void Main(string[] args) 
     { 
    wtoken = new CancellationTokenSource(); 
      readInputStream = Task.Factory.StartNew(() => 
      { 
       wtoken.Token.ThrowIfCancellationRequested(); 
       while (true) 
       { 
        if (wtoken.Token.IsCancellationRequested) 
        { 
         wtoken.Token.ThrowIfCancellationRequested(); 
        } 
        else 
        { 
         OpenStandardStreamIn(); 
        } 
       } 
      }, wtoken.Token 
      ); 
    Console.ReadLine(); 
} 

這裏是我的OpenStandardStreamIn功能

public static void OpenStandardStreamIn() 
     { 
       Stream stdin = Console.OpenStandardInput(); 
       int length = 0; 
       byte[] bytes = new byte[4]; 
       stdin.Read(bytes, 0, 4); 
       length = System.BitConverter.ToInt32(bytes, 0); 
       string input = ""; 
       for (int i = 0; i < length; i++) 
       { 
        input += (char)stdin.ReadByte(); 
       } 
       Console.Write(input); 
      } 

任何幫助嗎?爲什麼它不能連續循環工作

+0

「不工作」是什麼意思?究竟會發生什麼? – galenus 2014-11-04 06:37:10

+0

你在說什麼循環?如果這是你想要做的,你還沒有開始任何循環的新任務。你還沒有等待在ReadLine之前完成的Task。 – bit 2014-11-04 06:38:44

+0

@galenus:它只是在編譯時經歷一次,然後開始等待Console.ReadLine()的輸入。當我添加輸入它正在完成和dubugging停止 – 2014-11-04 06:40:26

回答

3

你基本上有一個Console.ReadLine和你的任務之間的競賽條件。他們都試圖從標準輸入中讀取 - 我當然不知道在從兩個線程同時讀取標準輸入時應該期待什麼,但似乎是值得避免的東西。

您可以通過更改任務來執行某些操作,比測試標準輸入更容易測試其他。例如:

using System; 
using System.Threading; 
using System.Threading.Tasks; 

class Test 
{ 
    static void Main() 
    { 
     var wtoken = new CancellationTokenSource(); 
     var readInputStream = Task.Factory.StartNew(() => 
     { 
      for (int i = 0; i < 10; i++) 
      { 
       Console.WriteLine(i); 
       Thread.Sleep(200); 
      } 
     }, wtoken.Token); 
     Console.ReadLine(); 
    } 
} 

如果你真正的代碼需要從標準輸入讀取,那麼我建議你改變Console.ReadLine()readInputStream.Wait()。如果您使用的是.NET 4.5,我也建議您使用Task.Run而不是Task.Factory.StartNew(),只是爲了便於閱讀 - 假設您不需要TaskFactory.StartNew中更深奧的行爲。

+0

謝謝你的答案喬恩。 Console.Readline只是一個便宜的技巧,可以避免應用程序停止。我需要讀取標準輸入流才能從chrome擴展中獲取消息。基本上它是一個本地消息應用程序。 – 2014-11-04 06:56:29

+0

我應該爲任務創建一個單獨的線程並使用Wait函數嗎?我怎樣才能讓控制檯應用程序連續執行? – 2014-11-04 06:58:10

+0

@Shiv:你爲什麼需要一個單獨的線程?如果您只需要從標準輸入讀取,只需從標準輸入讀取... – 2014-11-04 07:08:29