System.Threading.Timer导致其他计时器落后

时间:2012-04-08 21:34:30

标签: c# multithreading sockets timer timeout

我的第一篇文章,但这个网站回答了我过去的许多问题。希望我能够提供足够的细节来解释我面临的问题,因为我不完全理解所有.NET如何处理我创建的线程!

好吧基本上,我有一个线程设置为每1000ms运行一次,从视频编码器获取帧计数器并计算FPS。使用System.Threading.Timer准确度已经足够了,虽然我发现它不准确(事件之间通常超过1000毫秒)。我还有另一个Threading.Timer正在运行并从网络读取到串行设备。问题是如果网络设备变得不可用并且该计时器上的套接字超时,则FPS计时器完全不同步!所以他们之前每1015毫秒执行一次(测量),但当我启动另一个Thread.Timer试图建立套接字连接并且它失败时会导致FPS计数器计时器完全关闭(最多7000毫秒!!)。我不太清楚为什么这应该是,并且真的需要FPS计数器每秒运行一次,无论如何。

代码 - >

FPS计数器

private void getFPS(Object stateInfo)//Run once per second
{
    int frames = AxisMediaControl.getFrames; //Axis Encoder media control
    int fps = frames - prevValue;
    prevValue = frames;
    setFPSBar(fps, fps_color); //Delegate to update progress bar for FPS
}

电池电量计时器

while (isRunning)
{
    if (!comm.Connected) //comm is standard socket client
        comm.Connect(this.ip_address, this.port);   //Timeout here     causes     other timer threads to go out of sync

if (comm.Connected)
{
    decimal reading = comm.getBatt_Level();
    //Calculate Readings and update GUI
    Console.Out.WriteLine("Reading = " + (int)prog);
break;//Debug

        }

这是用于连接套接字的代码 - >

 public Socket mSocket { get; set; }
 public bool Connect(IPAddress ip_address, UInt16 port)
 {
    try
    {
        mSocket.Connect(ip_address, port);
    }
    catch(Exception ex)
    { 

    }
    return mSocket.Connected;   
}

希望不要太模糊!

2 个答案:

答案 0 :(得分:1)

虽然我不知道为什么你的FPS计时器没有被调用7s,但我可以建议一个解决方法:通过记住Environment.TickCount值来测量自上次更新FPS值以来的TimeSpan。然后,将FPS值计算为(delta_frames / delta_t)。

答案 1 :(得分:1)

感谢您的评论,我通过执行以下操作来修复它。

改为使用System.Timers.Timer并将auto-reset设置为false。每次其中一个定时器完成后我再次启动它,这意味着每个电池设备只有一个定时器。初始解决方案的问题是网络超时导致线程保持活动的时间比计时器间隔长得多。因此,为了确保满足计时器间隔,更频繁地产生新线程。

在运行期间,这意味着每个电池计时器大约有5-7个线程(其中6个是超时,1个即将开始)。更改为新计时器意味着现在只有一个线程应该是。

我还在代码中添加了根据所用时间计算FPS(使用秒表功能获得更高精度(感谢USR))。谢谢您的帮助。我必须确保不要将例外留空。