2017-08-17 67 views
0

我正在编写一个程序,它将消息发送并接收到另一个应用程序。 一些消息必须以特定的时间间隔发送。例如,我有四条发送的消息,每8秒发送一条消息,每0.5秒发送两条消息,每隔1秒发送一条消息。以正确的时间间隔不发生事件c#定时器

消息似乎发送正常,但他们都在同一时间发送。我使用时间戳来确定它们似乎每隔11秒就会发送一次。下面是我implimented代码:凡声明定时器的

这里是:

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

注意,当你可以用一个单独的['Write(toSend,0,toSend.Length)'](https://)写入整个字节数组并将每个单字节写入一个流时, msdn.microsoft.com/en-us/library/system.io.stream.write(v=vs.110).aspx)调用。使用DispatcherTimer类来避免调用Dispatcher.Invoke也是有意义的。 – Clemens

+0

@Clemens谢谢你的提示! –

回答

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(); 
+0

这工作完全谢谢你!我还没有看到过这样的定时器,请你能解释aysnc(s,e)部分,以便我能更好地理解? –

+1

请参阅[异步编程](https://docs.microsoft.com/zh-cn/dotnet/csharp/async)。 – Clemens

+0

谢谢! @Clemens –

0

日期是相同的,因为在Invoke运行的代码其的时间,就得调用之前拍摄日期:

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

这会解释11秒而不是0.5吗? – Clemens

+0

@Clemens,可能为所有消息合并了'TranslateToMessage'需要那么多。 – Sinatr

+0

嗨@Sinatr它似乎仍然每11秒发送一次。当我第一次尝试你的代码时,我意外地没有添加顶行,所以没有消息被发送,并且定时器正确显示,这可能表明错误在发送消息方法内而不是定时器本身。 –