0

我试图在 1 秒内尽可能多地调用一个方法,所以我决定使用计时器来帮助执行此操作,但是当计时器运行滴答事件处理程序时(1 秒后),该方法仍然被调用 -我已经开始如下:

public partial class Form1 : Form
    {
        public static Timer prntScreenTimer = new Timer();

        public Form1()
        {
            InitializeComponent();

            startCapture();
        }

        private static void startCapture()
        {
            prntScreenTimer.Tick += new EventHandler(prntScreenTimer_Tick);
            prntScreenTimer.Start();
            prntScreenTimer.Interval = 1000;
            while (prntScreenTimer.Enabled)
            {
                captureScreen();
            }

        }

        private static void prntScreenTimer_Tick(object sender, EventArgs e)
        {
            prntScreenTimer.Stop();
        }

        private static void captureScreen()
        {
            int ScreenWidth = Screen.PrimaryScreen.Bounds.Width;
            int ScreenHeight = Screen.PrimaryScreen.Bounds.Height;
            Graphics g;
            Bitmap b = new Bitmap(ScreenWidth, ScreenHeight);
            g = Graphics.FromImage(b);
            g.CopyFromScreen(Point.Empty, Point.Empty, Screen.PrimaryScreen.Bounds.Size);

            // Draw bitmap to screen
            // pictureBox1.Image = b;

            // Output bitmap to file
            Random random = new Random();
            int randomNumber = random.Next(0, 10000);
            b.Save("printScrn-" + randomNumber, System.Drawing.Imaging.ImageFormat.Bmp);
        }

    }
}
4

3 回答 3

3

我相信问题是你阻塞了主线程startcapture。表单 Timer 需要处理消息才能运行。将循环更改为:

    while (prntScreenTimer.Enabled)
    {
        captureScreen();
        Application.DoEvents();
    }

由于您不需要从您的方法访问 UI 线程,这会更好,因为它不会阻塞 UI:

private void startCapture()
{
    Thread captureThread = new Thread(captureThreadMethod);
    captureThread.Start();
}

private void captureThreadMethod()
{
   Stopwatch stopwatch = Stopwatch.StartNew();
   while(stopwatch.Elapsed < TimeSpan.FromSeconds(1))
   {
       captureScreen();
   }        
}
于 2012-05-26T18:26:11.187 回答
2

您的代码对我来说看起来是正确的,所以我无法确定您的问题的原因。但是,您实际上并不需要 a 来做Timer您正在做的事情。在循环中进行简单的Stopwatch检查while就足够了:

Stopwatch sw = Stopwatch.StartNew();
while (sw.ElapsedMilliseconds < 1000)
    captureScreen();
于 2012-05-26T18:24:03.997 回答
0

该方法被调用了多少次?您是如何计算的(无法从您粘贴的代码中得知)。
无论是哪种情况,您都必须记住 elapsed 事件在单独的线程上运行,因此这种竞争条件是可能的(您的方法在您停止计时器后运行一次甚至更多次)。当然有办法防止这种竞争条件。在 msdn 上存在一个有点复杂的示例

于 2012-05-26T18:24:22.173 回答