2012-05-26 4 views
0

Я пытаюсь вызвать метод столько раз, сколько возможно, учитывая его в течение 1 секунды, поэтому я решил использовать таймер, чтобы помочь выполнить это, но когда таймер запускается обработчик события клещ (после 1 секунды) метод еще вызывается - я начал его как следует:Invoke method x количество раз в течение x секунд

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); 
     } 

    } 
} 
+0

Каково ваше требование использовать таймер или просто вызвать метод? Если последнее, почему бы вам просто не создать базовый цикл с «проверкой, если период времени меньше 1 секунды» в качестве контура цикла? –

ответ

2

Ваш код выглядит правильно для меня, поэтому я не могу определить причину проблемы. Однако вам не нужен Timer за то, что вы делаете; простой Stopwatch проверяется в while цикла может быть достаточно:

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

Сколько раз вызывается метод? Как вы посчитали это (от кода, который вы вставляли) не может быть сказано.
В любом случае, вы должны помнить, что прошедшее событие запускается в отдельном потоке, и поэтому возможны такие условия гонки (ваш метод работает один или несколько раз после того, как вы остановили таймер). Конечно, есть способы предотвратить такие условия гонки. Несколько сложный пример для этого существует here, on the msdn

3

Я считаю, что проблема в том, что вы блокируете основной поток в startcapture. Формы Timer нуждаются в сообщениях, которые необходимо обработать для запуска. Изменение цикла к этому:

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

Поскольку вы не должны иметь доступ к резьбе 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(); 
    }   
} 
+0

+1: Я предполагаю, что это объясняет проблему. Хорошо поймал! – Douglas

+0

DoEvents могут заставить приложение работать, но я бы посоветовал прочитать эти ссылки, прежде чем использовать его http://www.codinghorror.com/blog/2004/12/is-doevents-evil.html http://stackoverflow.com/questions/5181777/use-of-application-doevents Это хорошее место, чтобы начать играть с потоками. –

+0

@ L.B Я полностью согласен. В лучшем случае DoEvents - это бандажная помощь. –