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。フォーム タイマーを実行するには、メッセージを処理する必要があります。ループを次のように変更します。

    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

あなたのコードは私には正しいように見えるので、問題の原因を特定できません。ただし、実際にやっていることには必要ありませんTimer。ループ内の単純なStopwatchチェックでwhile十分です。

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

メソッドが呼び出される回数は? これをどのように数えましたか (貼り付けたコードからはわかりません)。
いずれにせよ、経過したイベントは別のスレッドで実行されることを覚えておく必要があります。そのため、このような競合状態が発生する可能性があります (タイマーを停止した後にメソッドが 1 回以上実行される)。もちろん、このような競合状態を防ぐ方法はあります。これに対するやや複雑なサンプルが、msdn に存在します。

于 2012-05-26T18:24:22.173 に答える