2016-06-03 25 views
-1

ich einen Timer in meine einfache Anwendung haben:Fehler bei der Timer abgelaufen ist, und versuchen, neue Fenster C# zeigen

 System.Timers.Timer aTimer = new System.Timers.Timer(); 
     aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
     aTimer.Interval = 3000; 
     aTimer.Enabled = true; 

, die diese Funktion jedes Mal

private static void OnTimedEvent(object source, ElapsedEventArgs e) 
    { 
     ... 
     DisplayWindow displayedWindow = new DisplayWindow(); 
     displayedWindow.Show(); 
     ... 
    } 

und displayedWindow abgelaufen ist, ruft ist eine WPF Form, die nur den erzeugten Code haben sich (und meine schließen-Schaltfläche):

public partial class DisplayWindow : Window 
{ 
    public DisplayWindow() 
    { 
     InitializeComponent(); 
    } 

    private void cancelButton_Click(object sender, RoutedEventArgs e) 
    { 
     this.Close(); 
    } 
} 

, und wenn ich meine app laufen gibt es einen Fehler in Ort

public DisplayWindow() 

die Meldung wie diese haben:

"The calling thread must be STA, because many UI components require this". 

ich einige Threads zu lesen versuchte, und was habe ich gerade ist gefunden zu spielen STA Thread den ich gemacht habe, allerdings ohne Erfolg. Wie kann ich dieses Problem beheben?

Antwort

1

Wenn ein System.Timers.Timer in einer WPF-Anwendung verwendet wird, sollte beachtet werden, dass der System.Timers.Timer in einem anderen Thread als dem UI-Thread ausgeführt wird. Um auf Objekte im UI-Thread zugreifen zu können, müssen Sie die Operation mit Invoke oder BeginInvoke auf den Dispatcher des UI-Threads setzen. Gründe für die Verwendung eines DispatcherTimers im Gegensatz zu einem System.Timers.Timer sind, dass der DispatcherTimer auf demselben Thread wie der Dispatcher ausgeführt wird und eine DispatcherPriority auf dem DispatcherTimer festgelegt werden kann.

Betrachten wir ein DispatcherTimer für diese Verwendung:

var timer = new DispatcherTimer(); 
timer.Tick += OnTimedEvent; 
timer.Interval = TimeSpan.FromSeconds(3); 
timer.Start(); 

Und, ändern Sie Ihre Handler Signatur:

private static void OnTimedEvent(object sender, EventArgs e) 
1

Im Timer-Ereignis erfordert die Benutzeroberfläche Ihre Methode aufzurufen, ohne es den Aufruf auf der Stelle. Der UI-Thread ruft später Ihre Methode so bald wie möglich auf.

Dies ist ein Beispiel aus MSDN. Ich überlasse es Ihnen, Ihren Timer-Handler entsprechend anzupassen:

if (this.textBox1.InvokeRequired) 
{ 
    SetTextCallback d = new SetTextCallback(SetText); 
    this.Invoke(d, new object[] { text }); 
} 
else 
{ 
    this.textBox1.Text = text; 
}