2017-01-11 4 views
0

ich eine Anwendung, bei der eine Klasse I ein Windows Form und System.Threading.Timer bin initialisiert.Ausgabe mit System.Threading.Timer und Modal Showdialog()

Wenn die timer, die für einige IPC basierten Zeug hält prüft, einen bestimmten Wert feststellt, signalisiert er eine event in der gleichen Klasse, die dann ShowDialog() im Dialog zuvor initialisiert aufruft.

Leider stoppt diese ShowDialog()Modal, stoppt den Timer.

Ich hatte den Eindruck, dass System.Threaded.Timer wurde in einem anderen Thread zum aufrufenden Thread erstellt und so würde der Timer weiterhin im Hintergrund ausgeführt werden.

Bearbeiten - einige Code

public delegate void EventHandler(); 
class someClass 
{ 
    WrapperForm dlg = null; 
    public void CallToChildThread(Object stateInfo) 
    { 
     AutoResetEvent autoEvent = (AutoResetEvent)stateInfo; 
     //Check IPC 
     //Fire event 
     _show.Invoke(); 
    } 
    public someClass() 
    { 
     public static event EventHandler _show; 
     initializeDialog(); // Initialize the dialog. Standard new 
     var autoEvent = new AutoResetEvent(false); 
     var stateTimer = new System.Threading.Timer(CallToChildThread, 
            autoEvent, 1000, 250); 
     _show += new EventHandler(eventCheck); 
    } 
    void eventCheck() 
    { 
     //If some condition 
     dlg.ShowDialog(); //Timer stops 
    } 
} 

Wie dieses Problem gelöst werden könnte?

+1

Wenn Sie uns sehen könnten, was Sie (einige Code) versucht haben, wäre das toll. – EpicKip

+0

Ein Modal stoppt keinen Timer für mich o.O – EpicKip

+0

Code hinzugefügt. – user1173240

Antwort

2

Die Klasse System.Threading.Timer hat ein bekanntes Problem, bei dem, wenn Sie keinen Verweis darauf behalten, es vom Garbage Collector auch beim Ausführen gesammelt werden kann.

Wechseln Sie zur Verwendung System.Timers.Timer, die nur ein Wrapper um System.Threading.Timer ist oder behalten Sie einen Verweis auf den Timer, so dass der GC es nicht sammelt und Ihren Timer abbrechen.

public delegate void EventHandler(); 
class someClass 
{ 
    WrapperForm dlg = null; 
    System.Threading.Timer stateTimer; 
    public static event EventHandler _show; 

    public void CallToChildThread(Object stateInfo) 
    { 
     AutoResetEvent autoEvent = (AutoResetEvent)stateInfo; 
     //Check IPC 
     //Fire event 
     _show.Invoke(); 
    } 
    public someClass() 
    { 
     initializeDialog(); // Initialize the dialog. Standard new 
     var autoEvent = new AutoResetEvent(false); 
     stateTimer = new System.Threading.Timer(CallToChildThread, 
            autoEvent, 1000, 250); 
     _show += new EventHandler(eventCheck); 
    } 
    void eventCheck() 
    { 
     //If some condition 
     dlg.ShowDialog(); 
    } 
} 
+0

Ah, das war das Priblem. Ersetzen Sie es durch 'System.Timers.Timer' hat den Trick. Vielen Dank. Ist das Problem mit 'System.Threading.Timer' allgemein bekannt? – user1173240

1

Mit Ihrem Code, den ich mein Beispiel geändert, ich bin dein Timer jetzt mit (ich meine Timer noch mit so kann ich die anderen Timer sehen läuft noch)

public partial class Form1 : Form 
    { 
     Form frm1 = new Form(); 
     int i; 
     private System.Threading.Timer t; 
     //If the problem is garbage collecting then the line above is very important. 
     public Form1() 
     { 
      InitializeComponent(); 
      var autoEvent = new AutoResetEvent(false); 
      var stateTimer = new System.Threading.Timer(CallToChildThread, 
            autoEvent, 1000, 250); 
     } 
    private void CallToChildThread(object state) 
    { 
     i++; 
     //Updating value here, update in other timer (this is to avoid crossthreadEx) 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     frm1.ShowDialog(); 
     //Label keeps updating! 
    } 

    private void timer1_Tick(object sender, EventArgs e) 
    { 
     label1.Text = i.ToString(); 
    } 
} 

Es ist immer noch für mich arbeitet, Der Grund könnte sein, dass ich den Timer nicht zu einer lokalen Variable gemacht habe, sondern sie in der Klasse deklariert habe.

+0

Sie verwenden die falsche Art von Timer für Ihren Test, System.Threading.Timer hat kein "Tick" -Ereignis, es verwendet Delegate Callbacks. –

+0

Ich habe einen Code hinzugefügt. System.Threading.Timer hat keine Enabled-Eigenschaft. – user1173240