2011-12-07 8 views
17

Estoy tratando de entender por qué DispatcherTimer contenida dentro de SingletonWithTimer no se activa en la siguiente aplicación WPF. He estado investigando esto por un par de días y parece que no puedo llegar al fondo. Esta aplicación es la parte esencial reducida de una aplicación existente que estoy tratando de corregir. El objeto de inicio de este proyecto es WPFApplication5TimerTest.Program.DispatcherTimer no se activa en la aplicación WPF

La salida en las listas de la consola de la siguiente manera, el problema es evidente porque la palabra "fracción del temporizador" no se muestra en la salida:

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! 

Este es 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; 
     } 
    } 
} 

Ésta es 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);   
    } 
} 

Esta es MainWindow.x aml.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(); 
     } 
    } 
} 

Ésta es 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; 
    } 
} 

Respuesta

41

Es porque ha creado la DispatcherTimer en otro hilo (no-IU). Por lo tanto, estará ligado al Dispatcher en que el hilo, no el que está en el hilo de la interfaz de usuario. Como nada está ejecutando el Dispatcher en ese hilo, nunca se disparará.

Cualquiera de crear el DispatcherTimer en el hilo de interfaz de usuario, o utilizar un constructor overload que le permite pasar de una específica Dispatcher de usar.

+7

Por ejemplo: 'new DispatcherTimer (DispatcherPriority.Background, Application.Current.Dispatcher)' –

+0

@Kevin Kalitowski, excelente respuesta. Funciona perfectamente. ¡Gracias! – Elangesh

Cuestiones relacionadas