DispatcherTimer 在 WPF 应用程序中未触发

发布于 2024-12-19 21:04:15 字数 3651 浏览 0 评论 0原文

我试图理解为什么 SingletonWithTimer 中包含的 DispatcherTimer 在以下 WPF 应用程序中没有触发。我已经研究了几天,但似乎无法弄清楚它的真相。该应用程序是我正在尝试修复的现有应用程序的减少的基本部分。该项目的 Startup 对象是 WPFApplication5TimerTest.Program

控制台中的输出如下所示,问题很明显,因为输出中没有显示“TimerTick”一词:

Timer is initialized
'WpfApplication5TimerTest.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework.Aero\v4.0_4.0.0.0__31bf3856ad364e35\PresentationFramework.Aero.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Sample thread
Sample thread
Sample thread
Sample thread
Sample thread
Sample thread
The thread '<No Name>' (0x10b0) has exited with code 0 (0x0).
Sample thread exiting!

This is Program.cs:

using System;

namespace WpfApplication5TimerTest
{
    static class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            AppObject = new App();
            AppObject.Run();
        }

        public static App AppObject
        {
            get;
            private set;
        }
    }
}

This is App.xaml.cs:

using System;
using System.Threading;
using System.Windows;

namespace WpfApplication5TimerTest
{
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            var sampleThread = new Thread(new ThreadStart(SampleThreadEntryPoint));            
            sampleThread.Start();
            new MainWindow().Show();
        }

        private void SampleThreadEntryPoint()
        {
            SingletonWithTimer.Initialize();
            while (!_shutdownEvent.WaitOne(1000))
                Console.WriteLine("Sample thread");
            Console.WriteLine("Sample thread exiting!");
        }

        protected override void OnExit(ExitEventArgs e)
        {
            _shutdownEvent.Set();
        }

        private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);        
    }
}

This is MainWindow .xaml.cs:

using System;
using System.Windows;

namespace WpfApplication5TimerTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            Program.AppObject.Shutdown();
        }
    }
}

这是 SingletonWithTimer.cs:

using System;
using System.Windows.Threading;

namespace WpfApplication5TimerTest
{
    public class SingletonWithTimer
    {
        private static SingletonWithTimer Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new SingletonWithTimer();
                }
                return _instance;
            }
        }

        public static void Initialize()
        {
            SingletonWithTimer.Instance._timer = new DispatcherTimer();
            SingletonWithTimer.Instance._timer.Interval = TimeSpan.FromSeconds(2);
            SingletonWithTimer.Instance._timer.Tick += new EventHandler(SingletonWithTimer.Instance.OnTimerTick);
            SingletonWithTimer.Instance._timer.Start();
            Console.WriteLine("Timer is initialized");
        }

        private void OnTimerTick(object sender, EventArgs e)
        {
            Console.WriteLine("TimerTick");
        }

        private static SingletonWithTimer _instance;
        private DispatcherTimer _timer = null;
    }
}

I am trying to understand why the DispatcherTimer contained within SingletonWithTimer is not firing in the following WPF application. I've been researching this for a couple of days and cannot seem to get to the bottom it. This application is the reduced essential parts of an existing application that I'm trying to fix. The Startup object of this project is WPFApplication5TimerTest.Program.

The output in the console lists as follows, the problem is evident because the word "TimerTick" is not shown in the output:

Timer is initialized
'WpfApplication5TimerTest.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework.Aero\v4.0_4.0.0.0__31bf3856ad364e35\PresentationFramework.Aero.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Sample thread
Sample thread
Sample thread
Sample thread
Sample thread
Sample thread
The thread '<No Name>' (0x10b0) has exited with code 0 (0x0).
Sample thread exiting!

This is Program.cs:

using System;

namespace WpfApplication5TimerTest
{
    static class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            AppObject = new App();
            AppObject.Run();
        }

        public static App AppObject
        {
            get;
            private set;
        }
    }
}

This is App.xaml.cs:

using System;
using System.Threading;
using System.Windows;

namespace WpfApplication5TimerTest
{
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            var sampleThread = new Thread(new ThreadStart(SampleThreadEntryPoint));            
            sampleThread.Start();
            new MainWindow().Show();
        }

        private void SampleThreadEntryPoint()
        {
            SingletonWithTimer.Initialize();
            while (!_shutdownEvent.WaitOne(1000))
                Console.WriteLine("Sample thread");
            Console.WriteLine("Sample thread exiting!");
        }

        protected override void OnExit(ExitEventArgs e)
        {
            _shutdownEvent.Set();
        }

        private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);        
    }
}

This is MainWindow.xaml.cs:

using System;
using System.Windows;

namespace WpfApplication5TimerTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            Program.AppObject.Shutdown();
        }
    }
}

This is SingletonWithTimer.cs:

using System;
using System.Windows.Threading;

namespace WpfApplication5TimerTest
{
    public class SingletonWithTimer
    {
        private static SingletonWithTimer Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new SingletonWithTimer();
                }
                return _instance;
            }
        }

        public static void Initialize()
        {
            SingletonWithTimer.Instance._timer = new DispatcherTimer();
            SingletonWithTimer.Instance._timer.Interval = TimeSpan.FromSeconds(2);
            SingletonWithTimer.Instance._timer.Tick += new EventHandler(SingletonWithTimer.Instance.OnTimerTick);
            SingletonWithTimer.Instance._timer.Start();
            Console.WriteLine("Timer is initialized");
        }

        private void OnTimerTick(object sender, EventArgs e)
        {
            Console.WriteLine("TimerTick");
        }

        private static SingletonWithTimer _instance;
        private DispatcherTimer _timer = null;
    }
}

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

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

发布评论

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

评论(1

像你 2024-12-26 21:04:16

这是因为您在另一个(非 UI)线程上创建了 DispatcherTimer。因此,它将绑定到该线程上的调度程序,而不是 UI 线程上的调度程序。由于该线程上没有任何东西正在运行Dispatcher,因此它永远不会触发。

在 UI 线程上创建 DispatcherTimer,或者使用构造函数重载 允许您传入特定的 Dispatcher 来使用。

It's because you've created the DispatcherTimer on another (non-UI) thread. Hence, it will be tied to the Dispatcher on that thread, not the one on the UI thread. Since nothing is running the Dispatcher on that thread, it will never fire.

Either create the DispatcherTimer on the UI thread, or use a constructor overload that allows you to pass in a specific Dispatcher to use.

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