在 C# 中使用线程概念后,即使日期有效,也会引发无效日期异常


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.");
            }
        }
}

如果我不使用线程,它可以正常工作。但是如果我使用线程,即使输入的日期格式正确,也会给出"无效日期"异常。请提供解决方案。

您的主线程当前区域性可能与默认系统区域性不同。在 .NET Framework 4 和早期版本中创建新线程时,默认情况下,所有线程的区域性都设置为 Windows 系统区域性。

因此,您可以使用DateTime.ParseExact 并显式指定日期格式。

当你的代码到达Thread.Start时,它不会立即执行委托,而是继续并到达 main 方法中的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

您的问题与解析无关,我刚刚测试了您的代码,从您的主线程中删除 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");
            }
        }
    }

最新更新