在x秒的持续时间内调用方法x次

时间:2012-05-26 18:10:46

标签: c# .net windows

我试图在1秒内尽可能多地调用一个方法,所以我决定使用一个计时器来帮助执行这个,但是当计时器运行tick事件处理程序(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);
        }

    }
}

3 个答案:

答案 0 :(得分: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();
   }        
}

答案 1 :(得分:2)

您的代码对我来说是正确的,因此我无法确定您的问题的原因。但是,你真的不需要Timer来做你正在做的事情;在Stopwatch循环中检查的简单while可能就足够了:

Stopwatch sw = Stopwatch.StartNew();
while (sw.ElapsedMilliseconds < 1000)
    captureScreen();

答案 2 :(得分:0)

调用该方法的次数是多少?你怎么算这个(从你粘贴的代码中无法说出来)。
无论是什么情况,你必须记住经过的事件在一个单独的线程上运行,因此这样的竞争条件是可能的(你的方法在你计时器运行一次甚至更多之后运行)。当然有办法防止这种竞争条件。存在一些有点复杂的样本here, on the msdn