Windows Phone 计时器间隔不一致

发布于 2024-12-23 09:51:02 字数 1590 浏览 2 评论 0原文

我正在寻找使用 C# 创建一个 Windows Phone 应用程序。我想要一个计时器,它可以显示一张图像 100 毫秒,然后切换到另一张图像,然后再等待 900 毫秒,然后再次闪烁该图像。我写了下面的代码,但是,它似乎并没有一致地闪烁。有什么想法吗?

public partial class MainPage : PhoneApplicationPage
{
    DispatcherTimer timer = new DispatcherTimer();
    List<string> files = new List<string>() { "Images/off-light.png", "Images/on-light.png" };
    List<BitmapImage> images = new List<BitmapImage>();
    int current = 0;

    // Constructor
    public MainPage()
    {
        InitializeComponent();

        foreach (string file in files)
        {
            BitmapImage image = new BitmapImage(new Uri(file, UriKind.Relative));
            images.Add(image);
        }


            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(900);
            timer.Tick += new EventHandler(timer_Tick);

    }

    void timer_Tick(object sender, EventArgs e)
    {
        myImage.Source = images[current];
        current++;
        if (current >= files.Count)
        {
            current = 0;
            timer.Interval = TimeSpan.FromMilliseconds(100);
            timer.Stop();
            timer.Start();
        }
        else
        {
            timer.Interval = TimeSpan.FromMilliseconds(900);
            timer.Stop();
            timer.Start();
        }

    }

    private void btnStop_Click(object sender, RoutedEventArgs e)
    {
        timer.Stop();
        myImage.Source = images[0];
    }

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

I'm looking to create a windows phone application using C#. I want to have a timer that shows one image for 100 milliseconds then switches to another image and then waits another 900 milliseconds before it flashes the image again. I have the code below written, however, it doesn't seem to flash consistently. Any ideas?

public partial class MainPage : PhoneApplicationPage
{
    DispatcherTimer timer = new DispatcherTimer();
    List<string> files = new List<string>() { "Images/off-light.png", "Images/on-light.png" };
    List<BitmapImage> images = new List<BitmapImage>();
    int current = 0;

    // Constructor
    public MainPage()
    {
        InitializeComponent();

        foreach (string file in files)
        {
            BitmapImage image = new BitmapImage(new Uri(file, UriKind.Relative));
            images.Add(image);
        }


            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(900);
            timer.Tick += new EventHandler(timer_Tick);

    }

    void timer_Tick(object sender, EventArgs e)
    {
        myImage.Source = images[current];
        current++;
        if (current >= files.Count)
        {
            current = 0;
            timer.Interval = TimeSpan.FromMilliseconds(100);
            timer.Stop();
            timer.Start();
        }
        else
        {
            timer.Interval = TimeSpan.FromMilliseconds(900);
            timer.Stop();
            timer.Start();
        }

    }

    private void btnStop_Click(object sender, RoutedEventArgs e)
    {
        timer.Stop();
        myImage.Source = images[0];
    }

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

野味少女 2024-12-30 09:51:02

DispatchTimer 文档说:

定时器不保证在时间间隔发生时准确执行,但保证在时间间隔发生之前不执行。这是因为 DispatcherTimer 操作像其他操作一样被放置在 Dispatcher 队列中。 DispatcherTimer 操作何时执行取决于队列中的其他作业及其优先级。

我不知道这是否是导致您出现问题的原因,因为我从未使用过 DispatchTimer

您确实还有其他计时器选项。例如,您可以使用 System.Timers.Timer 或 System.Threading.Timer(我推荐使用 System.Timers.Timer,而不是 System.Timers.Timer)。但请注意,如果您使用这些计时器之一,则回调将在池线程上执行,并且您需要同步对 UI 线程的访问。再次来自 DispatchTimer 文档:

如果在 WPF 应用程序中使用 System.Timers.Timer,则值得注意的是 System.Timers.Timer 运行在与用户界面 (UI) 线程不同的线程上。为了访问用户界面 (UI) 线程上的对象,需要使用 Invoke 或 BeginInvoke 将操作发布到用户界面 (UI) 线程的 Dispatcher 上。使用 DispatcherTimer 而不是 System.Timers.Timer 的原因是 DispatcherTimer 与 Dispatcher 运行在同一线程上,并且可以在 DispatcherTimer 上设置 DispatcherPriority。

您可以考虑提高计时器的优先级吗?

The DispatchTimer documentation says:

Timers are not guaranteed to execute exactly when the time interval occurs, but they are guaranteed to not execute before the time interval occurs. This is because DispatcherTimer operations are placed on the Dispatcher queue like other operations. When the DispatcherTimer operation executes is dependent on the other jobs in the queue and their priorities.

I don't know if that's what's causing your problem, as I haven't ever worked with DispatchTimer.

You do have other options for timers. For example, you could use System.Timers.Timer or System.Threading.Timer (which I recommend over System.Timers.Timer). Do note, though, that if you use one of these timers the callback will be executing on a pool thread and you'll need to synchronize access to the UI thread. Again from the DispatchTimer documentation:

If a System.Timers.Timer is used in a WPF application, it is worth noting that the System.Timers.Timer runs on a different thread then the user interface (UI) thread. In order to access objects on the user interface (UI) thread, it is necessary to post the operation onto the Dispatcher of the user interface (UI) thread using Invoke or BeginInvoke. Reasons for using a DispatcherTimer opposed to a System.Timers.Timer are that the DispatcherTimer runs on the same thread as the Dispatcher and a DispatcherPriority can be set on the DispatcherTimer.

You might consider increasing the priority of your timer?

你曾走过我的故事 2024-12-30 09:51:02

我不太喜欢 winforms/wpf/silverlight,但我想说你需要使你的窗口无效。

调用刷新渲染所需的任何方法,因为我认为更改源图像不会触发刷新

i'm not much of a winforms/wpf/silverlight guy, but i'd say you need to invalidate your window.

call whatever method is needed to refresh the rendering, as I'd think changing the source image doesn't trigger a refresh

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文