如何从 Timer.Elapsed 事件触发另一个事件?

Posted

技术标签:

【中文标题】如何从 Timer.Elapsed 事件触发另一个事件?【英文标题】:How can I fire another event from a Timer.Elapsed event? 【发布时间】:2014-05-28 12:04:27 【问题描述】:

我有一个计时器,它每 5 秒轮询一次 GSM 调制解调器收到的新 SMS 消息,获取消息的代码工作正常,但我想每 5 秒不断检查新消息。

我的问题是,当我尝试从我的 Timer.Elapsed 事件中触发消失并收集这些消息的事件时,我收到 9 个错误,我已经像您执行任何其他方法一样调用了事件处理程序并试图通过适当的参数,但由于某种原因它不会编译!

代码如下,任何帮助将不胜感激=]

当它工作时,我打算参数化 SqlCommand!!!

计时器

 public void Pollback()
   
       Timer poller = new Timer(5000);
       poller.Enabled = true;
       poller.Start();
       if (poller.Interval==0)
       
           GsmPhone_MessageReceived(object sender, MessageReceivedEventArgs e);
       
   

用于处理来自调制解调器的传入消息的事件处理程序

public void GsmPhone_MessageReceived(object sender, MessageReceivedEventArgs e)
        
            Log("Message Received");

            //var message = GSM.ReadMessage(4);
            //GSM.ReadMessage(4);
            //TcpClientChannel client = new TcpClientChannel();
            //ChannelServices.RegisterChannel(client, false);
            //string url = "192.168.100.67:2000";
            //ISmsSender smssender = (ISmsSender)Activator.GetObject(typeof(ISmsSender), url);

            try
            

                SqlConnection Conn = new SqlConnection("Data Source=*********,****;Initial Catalog=******;User ID=********;Password=*******");
                SqlCommand com = new SqlCommand();
                com.Connection = Conn;
                Conn.Open();
                com.CommandText = ("INSERT INTO My_Table(ID,Message,Blacklist) VALUES(2,'"+GSM.ReadMessage(4).ToString()+"', 'Yes')");
                com.ExecuteNonQuery();
                Conn.Close();


            
            catch (Exception ex)
            
                var exception = ex.ToString();
                Log(exception);

            

【问题讨论】:

从事件处理程序中提取代码到单独的方法中,并从 GsmPhone_MessageReceived 处理程序和 Pollback 中调用此方法 当然!我真的应该知道,谢谢你们的帮助;你太有帮助了! 【参考方案1】:

基本上,您希望将其他事件的逻辑分解为一个单独的方法,然后在需要时调用该方法。

我修改了您的 SQL 查询以使用参数(更安全、更易于维护),并添加了一些 using 块,以便您在不再需要连接时自动关闭/释放连接。

另外,我不确定if (poller.Interval) == 0 怎么可能是true,因为您在实例化Timer 类时将间隔设置为5000 毫秒。如果您打算在间隔结束时调用该代码块,您可以从 Elapsed 事件中调用它。

public void Pollback()

    Timer poller = new Timer(5000);
    poller.Elapsed += (s, e) => InsertMessage();
    poller.Start();  // "Start()" sets "Enabled = true", so you don't need the other statement


public void GsmPhone_MessageReceived(object sender, MessageReceivedEventArgs e)

    InsertMessage();


private void InsertMessage()

    Log("Message Received");

    try
    
        using (var conn = new SqlConnection("Data Source=*********,****;Initial Catalog=******;User ID=********;Password=*******"))
        
            using (var com = new SqlCommand())
            
                com.Connection = conn;
                conn.Open();
                com.CommandText = ("INSERT INTO My_Table(ID,Message,Blacklist) VALUES(2, @Message, 'Yes')");
                com.Parameters.AddWithValue("@Message", GSM.ReadMessage(4).ToString());
                com.ExecuteNonQuery();
            
        
    
    catch (Exception ex)
    
        Log(ex.ToString());
    

【讨论】:

出色的回答格兰特,非常感谢!在我标记为已回答之前的最后一件事,我可以简单地在 Elapsed 事件上调用 InsertMessage,而不是像上面那样使用 If 语句吗?【参考方案2】:

Timer 构造函数的参数是间隔。由于您传入 5000,因此您的 if 语句将永远不会为真。您需要设置经过的事件以在触发计时器时调用该方法。您也不需要设置 Enabled 并调用 Start(),因为 Start() 只是将 Enabled 设置为 True。更多信息请参考文档:http://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx

为了通过一个事件调用两个方法,让事件触发一个回调并让该方法调用另外两个方法。

public void Pollback()

   Timer poller = new Timer(5000);
   poller.Elapsed = OnTimedEvent;
   poller.Enabled = true;


private void OnTimedEvent(Object source, ElapsedEventArgs e)
   GsmPhone_MessageReceived(source, e);
   secondMethod(source, e);

【讨论】:

以上是关于如何从 Timer.Elapsed 事件触发另一个事件?的主要内容,如果未能解决你的问题,请参考以下文章

Windows服务中的Timer Elapsed事件一一

在C#中Elapsed是什麽意思?

如何在Timer事件处理程序中获取Timer对象列表的列表索引

C# winform中timer函数如何停止,点运行后可再次启动周期事件

c# Timer异常停止

如何从另一个函数触发选择事件 [SAPUI5]