事件没有以正确的时间间隔发生c#定时器

时间:2017-08-17 09:36:28

标签: c# wpf timer

我正在编写一个程序,用于向另一个应用程序发送和接收消息。 某些消息必须以特定间隔发送。例如,我有四条消息被发送,一条应该每8秒发送一条,两条每0.5秒发送一条,每1秒发送一条消息。

这些消息似乎发送正常,但它们都是同时发送的。我使用时间戳确定它们似乎每11秒发送一次。下面是我所说的代码:

以下是宣布计时器的地方:

    System.Timers.Timer statusTimer = new System.Timers.Timer(1000);
    System.Timers.Timer heightTimer = new System.Timers.Timer(500);
    System.Timers.Timer keepAliveTimer = new System.Timers.Timer(8000);
    System.Timers.Timer longHeightTimer = new System.Timers.Timer(500);

在主窗口中它们被启动(这是一个WPF项目):

 statusTimer.Start();
 heightTimer.Start();
 keepAliveTimer.Start();
 longHeightTimer.Start();

  statusTimer.Elapsed += delegate { sendStatusMessage(); };
  heightTimer.Elapsed += delegate { sendHeightMessage(); };
  keepAliveTimer.Elapsed += delegate { sendKeepAliveMessage(); };
  longHeightTimer.Elapsed += delegate { sendLongWarpMessage(); };

以下是一个方法的示例,该方法应该在时间结束时被触发(显示它们并没有多大意义,因为它们基本相同):

 public void sendStatusMessage()
    {
        sendMessage(status_msg.TranslateToMessage());
        Dispatcher.Invoke(DispatcherPriority.Normal, (System.Action)delegate //change the priority so you can use UI
        {
            statusMsgLbl.Content = "Status Msg Sent: " + DateTime.Now.ToLongTimeString();
        });

    }

最后这个方法使用网络流将消息作为字节发送到另一个应用程序:

 public void sendMessage(byte[] toSend)
    {
        try
        {
            lock (NSLock)
            {
                for (int i = 0; i < toSend.Length; i++)
                {
                    nwStream.WriteByte(toSend[i]);
                    nwStream.Flush();
                }
            }
        }
        catch { MessageBox.Show("Unable to send message"); }
    }

2 个答案:

答案 0 :(得分:1)

您可以尝试将DispatcherTimer与异步Tick事件处理程序一起使用:

DispatcherTimer statusTimer = new DispatcherTimer
{
    Interval = TimeSpan.FromSeconds(1.0)
};

...

statusTimer.Tick += async (s, e) =>
{
    var message = status_msg.TranslateToMessage());

    await nwStream.WriteAsync(message, 0, message.Length);

    statusMsgLbl.Content = "Status Msg Sent: " + DateTime.Now.ToLongTimeString();
};

statusTimer.Start();

答案 1 :(得分:0)

日期是相同的,因为它是Invoke中运行的代码的日期,你必须在调用之前捕获日期:

public void sendStatusMessage()
{
    sendMessage(status_msg.TranslateToMessage());
    var text =  "Status Msg Sent: " + DateTime.Now.ToLongTimeString();
    Dispatcher.Invoke(() => statusMsgLbl.Content = text);