2014-09-26 26 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