事件未在正确的时间间隔c#计时器上发生

事件未在正确的时间间隔c#计时器上发生,c#,wpf,timer,C#,Wpf,Timer,我正在编写一个程序,它向另一个应用程序发送和接收消息。 有些信息必须以一定的间隔发送。例如,我有四条消息被发送,一条应该每8秒发送一次,两条应该每0.5秒发送一次,一条应该每1秒发送一次 这些消息似乎发送得很好,但它们都是同时发送的。我使用时间戳来确定它们似乎每11秒发送一次。下面是我实现的代码: 以下是计时器的声明位置: System.Timers.Timer statusTimer = new System.Timers.Timer(1000); System.Timers.

我正在编写一个程序,它向另一个应用程序发送和接收消息。 有些信息必须以一定的间隔发送。例如,我有四条消息被发送,一条应该每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项目):

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

最后,此方法使用网络流将消息(以字节形式)发送到其他应用程序:

 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"); }
    }
public void发送消息(字节[]toSend)
{
尝试
{
锁(NSLock)
{
for(int i=0;i
日期是相同的,因为它是在
调用中运行代码的日期,您必须在调用之前捕获日期:

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

您可以尝试将Dispatcher与异步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();

值得注意的是,当您可以通过一次调用写入整个字节数组时,将每个字节写入并刷新到流中似乎效率极低。使用Dispatchermer类来避免调用Dispatcher.Invoke也是有意义的。@Clemens谢谢你的提示!这能解释为什么是11秒而不是0.5秒吗?@Clemens,可能是所有信息都要花费那么多时间的组合
TranslateToMessage
。嗨@Sinatr,它似乎仍然每11秒发送一次。当我第一次尝试您的代码时,我无意中没有添加顶行,因此没有发送任何消息,并且计时器显示正确,这可能表明错误在send message方法中的某个位置,而不是计时器本身。我无法解释为什么
Invoke
延迟11秒,然后所有调用都会发生。也许你是在屏蔽用户界面?这非常有效,谢谢!我以前从未见过这样的计时器,请你解释一下aysnc(s,e)部分,以便我能更好地理解??看。谢谢@Clemens当写入流不会花费太多时间(例如,只需写入几个字节)时,在不使用async/await的情况下也应该可以正常工作。使用
nwStream.Write(…)
而不是
wait nwStream.WriteAsync(…)
public void sendStatusMessage()
{
    sendMessage(status_msg.TranslateToMessage());
    var text =  "Status Msg Sent: " + DateTime.Now.ToLongTimeString();
    Dispatcher.Invoke(() => statusMsgLbl.Content = text);
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();