C# 为啥定时器会自动停止

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 为啥定时器会自动停止相关的知识,希望对你有一定的参考价值。

请各位大虾告诉我一下,为什么我写的是C# asp.net 工具是vs2005,我写了一个自动定时发送邮件功能,为什么在局域网内,发送失败后就停止更新了呢?我觉得发送失败了,它的定时器不应该停啊

你用的什么定时器? asp.net程序是web程序, 一些winform程序的特性在这里是不能用的.
你定时发邮件应该单开线程进行, 并进行异常处理, 以便在出错时不会导致线程中止.
如果你是在页面处理程序中进行邮件发送的, 因为页面处理是有超时限制的, 你不可能让它一直运行下去. 而且如果异常没有捕获, 页面处理也会被中止.

另外Web服务器也有各种错误重置机制, 如果你的程序里有太多的异常没有被捕获可能会导致IIS服务器将你的应用程序重启, 一切处理将中断重来. 在指定的时间里没有任务页面请求也会导致IIS将你的应用停止以节约资源.

建议的方法是在启动你的邮件发送功能时新建一个线程, 并在这个独立的线程中进行邮件的发送的时间的等待. 使用线程同步机制的Wait方法来等待下一个发送时间的到来应该是比较好的方法.
参考技术A 下面的可以让Timer1运行100次后自动停止
if val(Timer1.tag)=100 then Timer1.Enable=false
...
Timer1.Tag=val(Timer1.Tag)+1

当窗口全屏或很大时,为啥 System.Windows.Forms.Timer 会自动停止?

【中文标题】当窗口全屏或很大时,为啥 System.Windows.Forms.Timer 会自动停止?【英文标题】:Why is System.Windows.Forms.Timer stopping automatically when window is fulscreen or is large?当窗口全屏或很大时,为什么 System.Windows.Forms.Timer 会自动停止? 【发布时间】:2020-10-27 17:12:39 【问题描述】:

根据在线示例,我使用 zXing 和 aForge 库在 c# 中编写了 qrcode 网络摄像头阅读器。 我在 C# 中遇到了 System.Windows.Forms.Timer 的非常奇怪的行为:我已将它放在寡妇窗体上,启用它,设置间隔 1 秒并附加刻度事件处理程序。

一切似乎都正常工作,但是当我将窗口调整(放大)到特定大小时,或者如果我将窗口设为全屏,时间滴答事件会停止触发。当我将窗口从全屏变为正常大小时,或者当我减小窗口大小时,计时器会自动重新启动。

我正在使用以下版本的 Visual Studio:

这是我的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using AForge.Video;
using AForge.Video.DirectShow;

using ZXing;

namespace QrCodeWebCamReader

    public partial class Form1 : Form
    
         
        FilterInfoCollection filterInfoColletion;
        VideoCaptureDevice captureDevice;

        public Form1()
        
            InitializeComponent();
        
        
        private void Form1_Load(object sender, EventArgs e)
         
            filterInfoColletion = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            foreach(FilterInfo filterInfo in filterInfoColletion)
            
                cboDevice.Items.Add(filterInfo.Name);
            
            cboDevice.SelectedIndex = 0;
        

        private void BtnStart_Click(object sender, EventArgs e)
        
            captureDevice = new VideoCaptureDevice(filterInfoColletion[cboDevice.SelectedIndex].MonikerString);
            captureDevice.NewFrame += CaptureDevice_NewFrame;
            captureDevice.Start();
            timer1.Start();
        

        private void CaptureDevice_NewFrame(object sender, NewFrameEventArgs eventArgs)
        

            // pictureBox.Image = (Bitmap)eventArgs.Frame.Clone();

            Bitmap img = (Bitmap)eventArgs.Frame.Clone(); 

            using (Graphics gr = Graphics.FromImage(img))
            
                gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

                Rectangle cropArea = new Rectangle(img.Width / 2 - 150, img.Height / 2 - 150, 300, 300);

                gr.DrawRectangle(new Pen(Color.Red,5), cropArea); 
            


            pictureBox.Image = (Bitmap)img.Clone();
        

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        
            timer1.Stop();
            if (captureDevice.IsRunning)
            
                captureDevice.Stop();
            
        

        private void Timer1_Tick(object sender, EventArgs e)
        
            System.Diagnostics.Debug.WriteLine("fungus");
            System.Diagnostics.Debug.WriteLine(pictureBox.Image);

            if(pictureBox.Image != null)
            
                Rectangle cropArea = new Rectangle(pictureBox.Image.Width / 2 - 150, pictureBox.Image.Height / 2 - 150, 300, 300);
                BarcodeReader barcodeReader = new BarcodeReader();
                Result result = barcodeReader.Decode((Bitmap)((Bitmap)pictureBox.Image).Clone(cropArea, pictureBox.Image.PixelFormat));
                picCropped.Image = (Bitmap)((Bitmap)pictureBox.Image).Clone(cropArea, pictureBox.Image.PixelFormat);
                if (result != null)
                
                    txtQRCode.Text += result.ToString();
                    Console.Beep();
                
             
        
    


我的项目配置为使用 net framework 2.0

此行为的原因可能是什么,我该如何防止它发生?

谢谢

编辑:关于这种行为,我能想到的唯一逻辑是编译器可能正在对生成的可执行代码进行某种优化/混淆/最小化? c# windows forms应用程序的Visual Studio社区版如何开启优化/混淆/最小化?

更新:仅当正在捕获视频时才会发生此行为。如果未捕获视频,则计时器不会停止。

【问题讨论】:

如果注释掉Timer1_Tick() 中除调试写入行之外的所有代码,它是否仍然停止工作? (我假设您连接了一个调试器来查看调试写入行输出。) Visual Studio 实际上并不运行您的代码(如果您愿意,您甚至可以使用记事本编写所有内容并通过命令行编译它而无需安装 Visual Studio)。您最好告诉我们您正在使用的框架的版本,因为它包含 WinForms 库。 @MatthewWatson 我已经列出了所有行,除了: System.Diagnostics.Debug.WriteLine("fungunsi");但行为是一样的 @John 我正在使用框架 2.0 “也许编译器正在做某种......” - 你在找错误的树。您的代码中有一个错误,某处。或者可能在您正在使用的库中(执行“帧捕获”的东西)。不幸的是,您未能提供minimal reproducible example,因此任何人都无法尝试重现您的问题以帮助您解决问题。请改进问题。 【参考方案1】:

经过广泛研究,我已将System.Windows.Forms.Timer 替换为System.Timers.Timer,一切开始正常工作,错误消失了。

我对@9​​87654323@ 的设置如下所示:

        System.Timers.Timer timer1;
  
        private void Form1_Load(object sender, EventArgs e)
        
            timer1 = new System.Timers.Timer(600);
            timer1.Enabled = true;
            timer1.SynchronizingObject = this;
            timer1.Elapsed += Timer1_Elapsed;
            timer1.Start();
 
        

但是,我仍然无法回答原始错误的原因是什么。任何有关此问题的信息都会很棒。

【讨论】:

这不是一个好主意,你现在有一个潜在的更大的问题。真正的问题是 UI 线程正在消耗 100% 的核心,试图跟上位图的大量绘制请求。不同之处在于底层的 Control.BeginInvoke() 调用以更高的优先级进行处理,结果是它现在还可以阻止处理用户输入。也许这还没有发生,但很可能会发生在速度较慢的机器或更大的显示器上。 正确的解决方法是使用您已经知道的,使用 winforms Timer 来更新 PictureBox。 @HansPassant 感谢您提供信息,我会记住这一点。但在我解决 winforms 计时器问题之前,我不得不坚持使用 System.Timers.Timer @HansPassant 自发布此答案以来,我一直在使用 System.Timers.Timer,从那时起我没有遇到过任何问题。可能是因为我的表单上没有用户输入,除了下拉列表,用户从中选择所需的视频输入设备?

以上是关于C# 为啥定时器会自动停止的主要内容,如果未能解决你的问题,请参考以下文章

C# 计时器的三种使用方法

c# - 如何立即停止计时器

C# 定时自动执行程序

Timer定时器过段时间后自动停止运行

使用spring 的定时器不懂为啥会执行两次

如何停止在 C# 类中运行的计时器