0

当我用F10按钮一步步调试这个小程序时,程序是有理的,直到达到关卡为止timer.Elapsed +=。在此之后它应该去调用我的方法Check(MyConn),但它没有!它回到MyConn.Close();并在这两者之间反弹,然后突然关闭程序!

我想知道问题出在哪里......它可能来自这一行:timer.Elapsed += (timerSender, timerEvent) => timer_Elapsed(timerSender, timerEvent, MyConn);?这是在这个论坛上发布的一个解决方案,以防我想提出MyConn论点timer_Elapsed......

在此先感谢您的帮助!

static void Main(string[] args)
{
    // create connection
    string ConnStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\mike\\Documents\\Database1.mdb;";

    OleDbConnection MyConn = new OleDbConnection(ConnStr);
    MyConn.Open();

    initTimer(MyConn);

    MyConn.Close();
}

static void initTimer(OleDbConnection MyConn)
{
    //set up a timer
    Timer timer = new Timer();
    timer.Interval = 2000; // check every 2s (2000ms) if the values in the database changed
    timer.Enabled = true; //enable the timer, so when the timer elapses after 2s, it performs some calculations

    timer.Elapsed += (timerSender, timerEvent) => timer_Elapsed(timerSender, timerEvent, MyConn);
}

static void timer_Elapsed(object sender, ElapsedEventArgs e, OleDbConnection MyConn)
{
    Check(MyConn); // Check is a method I have in my program which takes as argument "MyConn"
}
4

2 回答 2

3

这是完全正常的行为。

timer.Elapsed +=代码仅注册一个事件。2 秒后,该事件将被触发,但您的主线程将照常继续并返回到该Main()函数。然后它将调用MyConn.Close()并结束该Main()函数。

如果这是一个控制台应用程序,那么它将是程序的结束,这意味着事件没有时间timer_Elapsed运行。

如果它是一个将“保持活动状态”的应用程序,如服务或表单应用程序,那么当timer_Elapsed事件触发时,连接无论如何都已经关闭。


我建议如果您确实有一个“保持活力”应用程序,那么您应该将打开/关闭连接代码移动到实际使用它们的函数中。在这种情况下,这将在timer_Elapsed事件内部。

如果您没有“保持活力”应用程序,那么您可能应该完全避免使用计时器(以及任何具有单独线程的东西)。

顺便说一句,我一直在说“活着”,我希望你知道我的意思。我不知道用更专业的术语来描述它。

于 2013-05-03T11:12:09.180 回答
2

设置计时器后,您的代码将继续运行。它将离开该initTimer方法,然后关闭连接。之后,您的Main函数将退出,导致您的应用程序关闭。您的计时器也将终止。

如果您的程序没有被终止,计时器将从 2000 开始倒计时。当它达到零时,它将触发事件。这发生在另一个线程上,并且与您的主剧院平行发生。你甚至会检查连接,这显然会被关闭。

如果您希望主要威胁等到事件被触发,为什么还要使用计时器?为什么不这样做?

static void Main(string[] args)
{
    // create connection
    string ConnStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\mike\\Documents\\Database1.mdb;";

    using(OleDbConnection MyConn = new OleDbConnection(ConnStr))
    {
        MyConn.Open();
        do
        {
            Thread.Sleep(2000); 
            Check(MyConn);  
        }
        while(someValueToIndicateTheApplicationCanTerminate);
    }
}
于 2013-05-03T11:12:17.370 回答