2014-09-26 23 views
0
class Program 
    { 
     static void Main(string[] args) 
     { 
      Login loginObject = new Login();   
      int _loginTime = loginObject.login(); 
      Booking bookingObject = new Booking(); 
      bookingObject.booking(_loginTime); 
      new Thread(delegate() 
      { 
       bookingObject.booking(_loginTime); 
      }).Start(); 

      Console.ReadLine(); 
     } 
    } 

class Booking 
    { 
     public void booking(int _loginTime) 
     { 
      DateTime _date; 
      int _route; 
      int _option; 
      string _pan; 
      try 
      { 

       Console.WriteLine("Enter Date of journey(dd/mm/yyyy)"); 
       _date = Convert.ToDateTime(Console.ReadLine()); 
       //Code here 
      } 
      catch (FormatException) 
      { 
       Console.WriteLine("Invalid date."); 
      } 
     } 
} 

如果我不使用線程,它工作正常。但是如果我使用線程會給出「無效日期」異常,即使輸入的日期格式正確。 請提供解決方案。即使日期有效,在C#中使用線程概念後引發無效的日期異常

+1

嘗試使用DateTime.ParseExact與格式參數,而不是Convert.ToDateTime。您可能還想檢查異常詳細信息以瞭解異常的其他詳細信息 – tdragon 2014-09-26 14:10:36

+0

可能是在線程委託中的Console.ReadLine之前調用了main中的Console.Readline。你可以證明它添加了一些WriteLine來寫輸出和當前位置 – Steve 2014-09-26 14:25:34

回答

0

您的問題與解析無關,我剛剛測試了您的代碼,從主線程中刪除了Console.ReadLine,而不是使用Thread.Join停止主線程,直到生成的線程返回,請檢查下面的代碼,它按預期工作:

class Program 
    { 
     static void Main(string[] args) 
     { 
      //Login loginObject = new Login(); 

      //int _loginTime = loginObject.login(); 

      int logintime = 5; 

      Booking bookingObject = new Booking(); 

      bookingObject.booking(logintime); 

      Thread t = new Thread(delegate() { bookingObject.booking(logintime); }); 

      t.Start(); 

      t.Join(); 

      //Console.ReadLine(); 
     } 
    } 

    class Booking 
    { 
     public void booking(int logintime) 
     { 
      DateTime _date; 
      int _route; 
      int _option; 
      string _pan; 

      try 
      { 
       Console.WriteLine("Enter Date of journey(dd/mm/yyyy)"); 
       string str = Console.ReadLine(); 
       _date = Convert.ToDateTime(str); 


       //_date = DateTime.Parse(str); 
       //Code here 
      } 
      catch (FormatException) 
      { 
       Console.WriteLine("Invalid date."); 
      } 
      catch (Exception) 
      { 
       Console.WriteLine("Exception Returns"); 
      } 
     } 
    } 
+0

事實上,發生的情況顯然是主線程訪問相同的控制檯對象,以及將作爲DateTime的輸入接收什麼。解析函數實際上是一個按鍵而不是日期字符串,因此例外,請嘗試它 – 2014-09-26 14:37:22

1

也許你的主線程當前的文化不同於默認的系統文化。在.NET Framework 4和以前的版本中創建新線程時,默認情況下,所有線程的區域設置爲Windows系統區域性。

因此,您可以使用DateTime.ParseExact並明確指定日期格式。

+0

主線程文化將如何不同,除非在代碼中明確指定。即使文化差異在日期解析中看到的結果與預期不同,它也不會導致格式異常。在這裏主線程調用是成功的,但問題在於產生線程,從主線程spwaned的任何線程將具有相同的文化,直到和除非明確指定 – 2014-09-26 16:03:44

+0

任何線程的默認文化是Windows系統文化。請檢查[MSDN](http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.defaultthreadcurrentculture%28v=vs.110%29.aspx)。 'Convert.ToDateTime'是文化特定的,並且使用線程的當前文化。因爲這種無效的文化可能是問題的原因。 – Nikita 2014-09-26 18:24:01

+0

您是否試圖瞭解該評論,請允許我幫忙: - 此代碼中的顯式線程文化在哪裏設置?指出。 - 爲什麼不同的文化會導致異常,這隻會是不同的結果,不同的格式。提供示例。 在windows中,一切工作在線程上,所以在任何情況下,可配置的屬性總是適用於在線程上執行的代碼,這是從一開始就沒有新東西。 – 2014-09-27 12:43:25

1

當你的代碼達到Thread.Start它不會立即執行的委託,而是繼續和達到的主要方法Console.Readline。此時系統啓動線程委託,但第一個輸入是主線程中的Console.ReadLine
隨後的Console.ReadLine是在您的線程中使用並轉換爲日期的一個。

你可以試試你的代碼這款改裝版....

static AutoResetEvent are = null; 

static void Main(string[] args) 
{ 
    Booking bookingObject = new Booking(); 
    Console.WriteLine("First call to booking in Main"); 
    bookingObject.booking(100); 

    new Thread(delegate() 
    { 
     Console.WriteLine("Thread starting"); 
     bookingObject.booking(100); 
    }).Start(); 

    Console.WriteLine("Console.Readline in Main"); 

    // Comment these two lines to reproduce the original behavior 
    are = new AutoResetEvent(false); 
    are.WaitOne(); 

    string s = Console.ReadLine(); 
    Console.WriteLine("Result from main readline" + s); 
} 

class Booking 
{ 
    public void booking(int _loginTime) 
    { 
     DateTime _date; 
     int _route; 
     int _option; 
     string _pan; 
     try 
     { 
      Console.WriteLine("Enter Date of journey(dd/mm/yyyy)"); 
      string s = Console.ReadLine(); 
      Console.WriteLine("User input catched inside the thread: " + s); 
      _date = Convert.ToDateTime(s); 
      if(are != null) are.Set(); 
     } 
     catch (FormatException) 
     { 
      Console.WriteLine("Invalid date."); 
     } 
    } 
} 

當然建議當輸入不在你的控制仍然是非常有效的使用更強大的轉換代碼。 DateTime.TryParseDateTime.TryParseExact應該使用

+0

想法保持不變,主線程需要使用正確的機制而不是ReadLine等待,這就是此問題的主要原因,無論是等待信號(自動重置/手動重置)或簡單連接。 – 2014-09-26 14:45:33

+0

@MrinalKamboj正好。控制檯讀/寫仍然可以顯示代碼流的簡單跟蹤,無論AutoResetEvent是否支持同步 – Steve 2014-09-26 14:56:39