2017-05-26 9 views
0

Ich habe vor kurzem angefangen zu lernen C#, ich versuche, eine Methode jede Minute mit Hilfe eines Timers zu wiederholen. Die Methode ändert den Wert des Labels. Allerdings erhalte ich folgende Fehlermeldung:C# - Winforms - Wiederholungsmethode mit Hilfe des Timers

$exception {"Cross-thread operation not valid: Control 'label1' accessed from a thread other than the thread it was created on."} System.Exception {System.InvalidOperationException}

Ich habe versucht, nach einer Lösung zu suchen, und jeder Thread verwirrt mich. Ich brauche nicht nur den richtigen Code, sondern auch eine Erklärung, da ich lernen möchte, die Benutzeroberfläche mithilfe von Timern und Threading zu manipulieren.

Nachstehend ist mein Code:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Timers; 
using System.Windows.Forms; 



namespace Winforms_Timer_and_Thread 
{ 
    public partial class Form1 : Form 
    { 

     System.Timers.Timer myTimer = new System.Timers.Timer(); 
     public Form1() 
     { 
      myTimer.Enabled = true; 
      InitializeComponent(); 
     } 

     public void startMethod(object senter, ElapsedEventArgs e) 
     { 
      int cntr = 0; 
      cntr++; 
      label1.Text = "Executed: " + cntr.ToString(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      label1.Text = "Started!"; 
      myTimer.Enabled = true; 
      myTimer.Interval=(1*60*1000); 
      myTimer.Elapsed += new System.Timers.ElapsedEventHandler(startMethod); 

     } 

    } 
} 
+0

https Siehe: // stackoverflow.com/questions/661561/how-to-update-the-gui-from-another-thread-in-c Sie können nicht direkt von Nicht-Ui-Thread auf UI zugreifen. –

+2

Sie können stattdessen auch einen System.Windows.Forms.Timer verwenden. –

+0

@ James R. Aber ist es dann möglich, die Methode jede Minute aufzurufen? – Tango

Antwort

2

Wenn Sie ein System.Windows.Forms.Timer verwenden ändern, werden Sie dieses Problem nicht, da sie in dem gleichen UI-Thread ausgeführt wird.

Sie müssen nur ändern:

  • Die Art des Timers von System.Timers.Timer zu System.Windows.Forms.Timer
  • Das Ereignis, das zu Elapsed-Tick
  • Die Veranstaltung Unterschrift gezeichnet wird, wo ElapsedEventArgs e wird EventArgs e

Sie müssen auch nur das Ereignis abonnieren einmal, nicht jedes Mal, wenn der Timer aktiviert ist, so verschieben Sie das stattdessen zum Ereignis, zusammen mit der Interval Zuweisung (obwohl das jederzeit geändert werden kann).

Sie könnten auch außerhalb des StartMethod die Zählervariable gespeichert werden sollen, so erhöht er jedes Mal, wenn der ausgeführt wird, und es dann zurückgesetzt jedes Mal auf Null starten Sie den Timer:

public partial class Form1 : Form 
{ 
    readonly System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer(); 
    private int tickCounter; 

    public Form1() 
    { 
     InitializeComponent(); 

     myTimer.Interval = (int)TimeSpan.FromMinutes(1).TotalMilliseconds; 
     myTimer.Tick += StartMethod; 
    } 

    private void StartMethod(object sender, EventArgs e) 
    { 
     tickCounter++; 
     label1.Text = "Number of executions: " + tickCounter; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     tickCounter = 0; 
     label1.Text = "Started!"; 
     myTimer.Enabled = true; 
    } 
}