WPF 应用中 DispatcherTimer 未触发

18

我正在尝试理解为什么以下WPF应用程序中的SingletonWithTimer包含的DispatcherTimer没有触发。我已经研究了几天,但似乎无法找到问题的根源。这个应用程序是现有应用程序的必要部分,我正在努力修复它。该项目的启动对象是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!

这是 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;
        }
    }
}

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

这是 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;
    }
}
1个回答

50

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

要么在 UI 线程上创建 DispatcherTimer,要么使用允许您传入特定 Dispatcher构造函数重载


8
例如:new DispatcherTimer(DispatcherPriority.Background, Application.Current.Dispatcher) - Kevin Kalitowski
@Kevin Kalitowski,回答得非常好。完美地运行。谢谢! - manu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接