2013-03-02 92 views
1

我想在wpf vs 2010中制作一个按钮,点击时会定期执行一个动作,我已经看过这个和其他网站上的一吨不同的类似问题,但问题是我试图调用功能,从一个kinect截图,可以得到一个计时器工作,但它保持冻结,而不是10个不同的截图2.5秒的间隔我一次又一次地得到相同的截图,任何帮助非常赞赏。 目前我使用复选框而不是按钮,因为我在这里找到了一些提示。定时器麻烦。 。

private void checkBox1_Checked_1(object sender, RoutedEventArgs e) 
    { 

     Stopwatch stopwatch = new Stopwatch(); 

     // Begin timing 
     stopwatch.Start(); 

     // Do something 
     for (int i = 0; i < 60000; i++) 
     { 
      Thread.Sleep(3); 
     } 

     // Stop timing 
     stopwatch.Stop(); 

     take_motions(); 
    } 
+0

你在这里只是时间需要多长时间睡眠60K倍大致〜10ms的流行发布的代码;线程睡眠的粒度大约为10毫秒,加或减。 – JerKimball 2013-03-02 15:54:30

回答

0

有WPF中一个专门的定时器类,避免了交叉UI线程的问题,因为它在UI线程中运行。这是DispatcherTimer类:

private DispatcherTimer timer; 

public MainWindow() 
{ 
    InitializeComponent(); 

    timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(2.5) }; 
    timer.Tick += timer_Tick; 
} 

private void timer_Tick(object sender, EventArgs e) 
{ 
    // take screenshot here 
} 

private void checkBox_Checked(object sender, RoutedEventArgs e) 
{ 
    timer.Start(); 
} 

private void checkBox_Unchecked(object sender, RoutedEventArgs e) 
{ 
    timer.Stop(); 
} 
1

使用此代码,您将阻止主应用程序线程。这将解释为什么你一遍又一遍地得到相同的屏幕截图。

你需要做的是在后台线程中启动计时器,然后形成那个线程发送一个事件给主应用程序拍屏幕截图。这将允许应用程序继续工作。

要做到这一点,你应该使用Timer类之一。它们各自的工作方式稍有不同,但都应该允许您指定一个要在计时器的每个滴答声上调用的方法。

您需要将事件发送回用户界面以避免跨线程问题。

+0

酷我会尽力谢谢:) – H65 2013-03-02 13:35:31

1

你应该在一个单独的线程中使用定时器和运行take_motions();

aTimer = new System.Timers.Timer(10000); 

// Hook up the Elapsed event for the timer. 
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 

// Set the Interval to 2 seconds (2000 milliseconds). 
aTimer.Interval = 2000; 
aTimer.Enabled = true; 

private void checkBox1_Checked_1(object sender, RoutedEventArgs e) 
{ 
    //here call timer start or stop 
} 

private static void OnTimedEvent(object source, ElapsedEventArgs e) 
{ 
    ThreadPool.QueueUserWorkItem(delegate 
    { 
    take_motions(); 
    }); 
}