C# 为什么当窗口为fulscreen或较大时System.Windows.Forms.Timer会自动停止?
根据在线示例,我在c#uzing zXing和aForge库中编写了qrcode网络摄像头阅读器。 我在C#中遇到了非常奇怪的C# 为什么当窗口为fulscreen或较大时System.Windows.Forms.Timer会自动停止?,c#,zxing,aforge,C#,Zxing,Aforge,根据在线示例,我在c#uzing zXing和aForge库中编写了qrcode网络摄像头阅读器。 我在C#中遇到了非常奇怪的System.Windows.Forms.Timer行为:我把它放到widows窗体上,启用它,设置间隔1秒并附加了tick eventhandler 一切似乎都正常工作,但当我将窗口调整(放大)到特定大小时,或者如果我使窗口全屏显示,times tick事件停止触发。当我将窗口从全屏调到正常大小时,或者当我减小窗口大小时,计时器会自动重新启动 我正在使用以下版本的vis
System.Windows.Forms.Timer行为:我把它放到widows窗体上,启用它,设置间隔1秒并附加了tick eventhandler
一切似乎都正常工作,但当我将窗口调整(放大)到特定大小时,或者如果我使窗口全屏显示,times tick事件停止触发。当我将窗口从全屏调到正常大小时,或者当我减小窗口大小时,计时器会自动重新启动
我正在使用以下版本的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();
}
}
}
}
}
我的项目已配置为使用NETFramework 2.0
这种行为的原因可能是什么?我如何防止这种情况发生
多谢各位
编辑:关于这种行为,我能想到的唯一逻辑是编译器可能正在对生成的可执行代码进行某种优化/模糊化/最小化?如何在visual studio社区版c#windows窗体应用程序中实现优化/模糊处理/最小化
更新:只有在捕获视频时才会发生此行为。如果视频没有被捕获,计时器就不会停止。经过广泛的研究,我用System.Timers.timer
替换了System.Windows.Forms.timer
,一切都开始正常工作,错误消失了
我对System.Timers.Timer
的设置如下所示:
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();
}
但是,我仍然不知道最初错误的原因是什么。关于这个问题的任何信息都很好。如果您注释掉Timer1\u Tick()
中除调试写入线以外的所有代码,它是否仍然停止工作?(我假设您附加了一个调试器来查看调试writeline输出。)Visual studio实际上并没有运行您的代码(如果需要,您甚至可以使用记事本编写所有内容并通过命令行进行编译,而不必安装Visual studio)。最好告诉我们您正在使用的框架的版本,因为它包含WinForms库。@MatthewWatson我已经列出了所有行,除了:System.Diagnostics.Debug.WriteLine(“fungunsi”);但行为是不公平的same@John我使用的是Framework2.0“也许编译器正在做一些……”——你找错了方向。你的代码中某处有一个bug。或者可能在您正在使用的库中(执行“帧捕获”的东西)。不幸的是,您未能提供一个解决方案,因此,任何人都不可能费心复制您的问题来帮助您解决问题。请改进这个问题。这不是一个好主意,你现在有一个潜在的更大的问题。真正的问题是UI线程正在燃烧100%的内核,试图跟上位图绘制请求的洪流。不同之处在于,底层的Control.BeginInvoke()调用以更高的优先级进行处理,其结果是它现在还可以阻止处理用户输入。也许这还没有发生,但可能发生在速度较慢的机器或更大的显示器上。正确的解决方法是使用您已经知道的,使用winforms计时器更新PictureBox。@HansPassant谢谢您提供的信息,我会记住这一点。但在解决winforms计时器问题之前,我必须坚持使用System.Timers。Timer@HansPassant自从发布这个答案以来,我一直在使用System.Timers.Timer,从那以后我就没有遇到过任何问题。可能是因为我的表单上没有用户输入,除了下拉列表,用户从中选择所需的视频输入设备?