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