Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# System.Threading.Timer导致其他计时器落后_C#_Multithreading_Sockets_Timer_Timeout - Fatal编程技术网

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

C# System.Threading.Timer导致其他计时器落后,c#,multithreading,sockets,timer,timeout,C#,Multithreading,Sockets,Timer,Timeout,我在这里的第一篇帖子,但这个网站回答了我过去遇到的许多问题。希望我能提供足够的细节来解释我面临的问题,因为我不完全理解所有.NET是如何处理我创建的线程的 好的,基本上,我有一个线程设置为每1000毫秒运行一次,它从一个视频编码器获得一个帧计数器,并计算FPS。虽然我意识到System.Threading.Timer不够精确(事件之间的间隔通常超过1000毫秒),但现在已经足够精确了。我还有另一个Threading.Timer,它正在运行,并从网络读取串行设备的数据。问题是,如果网络设备变得不可

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

好的,基本上,我有一个线程设置为每1000毫秒运行一次,它从一个视频编码器获得一个帧计数器,并计算FPS。虽然我意识到System.Threading.Timer不够精确(事件之间的间隔通常超过1000毫秒),但现在已经足够精确了。我还有另一个Threading.Timer,它正在运行,并从网络读取串行设备的数据。问题是,如果网络设备变得不可用,并且该计时器上的套接字超时,FPS计时器将完全不同步!所以他们以前每1015ms(测量)执行一次,但当我启动另一个线程时。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;   
}

希望不要太模棱两可

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

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

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

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


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

为什么隐藏异常是个好主意?该软件将用于存在大量超时的环境中,我不认为每5秒显示一条消息会有多大用处。我在调试时捕捉到异常,但我预计连接有时会失败,因为网络是无线的,并且在操作过程中可能会出现断开。您有什么建议?我建议捕获
TimeoutException
或您关心的任何特定异常,并允许其他异常传播。这样,您将了解其他例外情况。谢谢您的回复。我确实认为这很奇怪,我不确定它是否与.NET的线程池有关,因为在测试完整应用程序时,我有大约5个线程每秒计算帧数,4个线程每秒计算电池读数。有时,该软件似乎在任务管理器中使用了多达90个线程,这似乎太高了。。!解决办法当然是一个选择,但我希望我能找到问题的根源,如果可能的话!90个线程太多了。您可能遇到了一些线程池限制,导致计时器ping无法执行。我建议您查看调试器中的“线程”窗口,了解为什么有这么多线程。请注意,Threading.Timer不会阻止线程,因此这可能不是原因。只是想知道,当看到它运行时,许多线程似乎都是为套接字客户端创建的,因此必须对此进行研究。它似乎也在使用线程来更新FPS计数器的接口(我使用了一个委托),这是更新接口的坏方法吗?因为每个计时器都通过一个委托进行更新,这似乎在运行时添加了额外的线程。因此,当观看4个视频流时,这个问题被放大了!计时器到期时,回调将排入线程池队列。只有在执行时,才会使用线程。等待下一个滴答声时不使用线程,回调在队列中时不使用线程。这绝对是正确的方法。不过,电池电量计时器似乎处于无限循环中。它正在用光一根线。只要你有一个小的固定数量的他们(4)这不是一个问题。