2012-04-08 68 views
1

我在这里的第一篇文章,但这个网站已经回答了我以前有过的许多问题。希望我可以提供足够的细节来解释我所面临的问题,因为我不完全理解.NET如何处理我创建的线程!System.Threading.Timer导致其他计时器落后

好吧,所以基本上,我有一个线程设置为每1000ms运行一次从视频编码器获取帧计数器并计算FPS。尽管我意识到它不准确(通常在事件之间超过1000毫秒),但对于现在的System.Threading.Timer来说,精度足够了。我还有另一个Threading.Timer正在运行并从网络读取串行设备。问题是,如果网络设备变得不可用,并且该定时器上的套接字超时,则FPS定时器将完全不同步!所以他们以前每1015ms执行一次(测量),但是当我启动另一个Thread.Timer尝试进行套接字连接并且失败时,它会导致FPS计数器定时器完全关闭(最高7000ms!)。我不太清楚为什么会这样,而且真的需要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; 
} 

Hope完全不太含糊!

+0

为什么隐藏异常是一个好主意? – 2012-04-08 21:37:00

+0

该软件将用于会出现很多超时的环境中,并且我认为每5秒钟不会显示一条消息会很有用。我在调试时发现异常,但我期望连接失败,因为网络是无线网络,并且在操作期间预计会出现退出。你会建议什么? – jackocurly0074 2012-04-08 21:40:08

+2

我建议捕捉'TimeoutException'或任何你关心的特定异常,并允许其他人传播。这样,你会了解其他例外情况。 – 2012-04-08 23:56:09

回答

1

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

+0

感谢您的回复。我认为这很奇怪,不确定它是否与线程池有关。当测试完整的应用程序时,我有大约5个线程计算每秒帧数和4个电池读数。此外,有时该软件似乎在任务管理器中使用多达90个线程,这似乎高得多......!解决方法绝对是一种选择,但我希望如果可能的话,我可以找到问题的根源! – jackocurly0074 2012-04-08 21:48:54

+2

90个线程太多了。您可能会在此处遇到一些线程池限制,导致定时器ping不被执行。我建议你看看调试器中的线程窗口,看看为什么有这么多的线程。注意,Threading.Timer不会阻塞一个线程,所以这可能不是原因。 – usr 2012-04-08 21:51:14

+0

只是想知道,在看它运行时,看起来很多线程是为套接字客户端创建的,因此必须查看它。它也似乎是使用线程来更新FPS计数器的接口(我使用委托),这是更新接口的不好方法吗?由于每个计时器通过委托进行更新,这似乎是在运行时添加额外的线程。所以当观看4个视频流时,这个问题就被放大了! – jackocurly0074 2012-04-08 22:22:21

1

感谢您的评论,我通过以下操作修复了这一问题。

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

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

我还在代码中添加了基于所需时间计算FPS的方法(使用Stopwatch功能获得更高精度(谢谢USR))。谢谢您的帮助。我必须确保不要让例外空白。