2016-06-08 10 views
0

Ich habe eine lange Verarbeitung in meinem Winform, wenn ich auf eine Schaltfläche klicke; nämlich lade ich viele Dateien und verarbeite sie. Für die Dauer der Verarbeitung ist meine GUI eingefroren und reagiert nicht mehr, was ein Problem darstellt, da die Verarbeitung mehr als 10 Minuten dauern kann. Gibt es eine Möglichkeit, den Code in eine Art Bubble oder ähnliches zu setzen, damit ich die GUI während der Verarbeitung der Dateien verwenden kann? Vielleicht fügen Sie sogar die Schaltfläche "Abbrechen" hinzu.Responsive GUI während der Verarbeitung aktivieren

EDIT: René-Lösung arbeitet, auch hier ist progressbar Kontrolle Ich wollte auch:

private async void button1_Click(object sender, EventArgs e) 
    { 
     progressBar1.Maximum = ValueWithTOtalNumberOfIterations.Length; 
     IProgress<int> progress = new Progress<int>(value => { progressBar1.Value = value;}); 

     await Task.Run(() => 
     { 
      var tempCount = 0; 

     //long processing here 
     //after each iteration: 

      if (progress != null) 
      { 
       progress.Report((tempCount)); 
      } 
      tempCount++;   
     }    
    } 
+2

Blick auf async/erwarten https://msdn.microsoft.com/en-us/library/mt674882.aspx –

+1

Sie Background verwenden können. Verweisen Sie auf diesen Link - https://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx Verwenden Sie die CancelAsync-Methode, um den Vorgang abzubrechen. – Sanket

+1

Ja, es gibt verschiedene Möglichkeiten, dies zu erreichen. Sie sollten wahrscheinlich nach async-await suchen (wenn Sie net fw 4.5 oder höher verwenden), da Sie dies bereits richtig getaggt haben und dann mit Ihrem Versuch kommen;) – Mono

Antwort

2

Sie könnten einfach Ihre Schaltfläche Click-Handler async machen und ein Task für Ihren langen laufenden Betrieb starten:

public async void button1_Click(object sender, EventArgs e) 
{ 
    button1.Enabled = false; // disable button to not get called twice 

    await Task.Run(() => 
    { 
     // process your files 
    } 

    button1.Enabled = true; // re-enable button 
} 

Der Compiler verwandelt dies in eine Zustandsmaschine. Der Kontrollfluss wird an den Aufrufer (UI) unter dem Schlüsselwort await zurückgegeben. Und die Ausführung dieser Methode wird fortgesetzt, wenn Ihre Task abgeschlossen ist.


Um eine „Abbrechen“ verwenden -Button Sie eine TaskCancellationSource oder einfach definieren ein Flag verwenden können, die Sie überprüfen, während Sie Ihre Dateien sind Verarbeitung und zurück, wenn das Flag (durch den Klick-Handler gesetzt ist Ihre Schaltfläche "Abbrechen"):

private bool _stop = false; 

private void cancelButton_Click(object sender, EventArgs e) 
{ 
    _stop = true; 
} 
private async void button1_Click(object sender, EventArgs e) 
{ 
    button1.Enabled = false; // disable button to not get called twice 

    _stop = false; 

    await Task.Run(() => 
    { 
     // process your files 
     foreach(var file in files) 
     { 
      if (_stop) return; 
      // process file 
     } 
    } 

    button1.Enabled = true; // re-enable button 
} 
+0

Das ist großartig, danke! Aber ich erhalte jetzt einen Fehler in meinem Code, wie ThreadStateException in meinem 'DialogResult result = folder.ShowDialog();'. Sagt, dass der aktuelle Thread auf STA-Modus festgelegt werden muss, bevor OLE-Aufrufe vorgenommen werden können. Ich weiß, ich sollte das hier nicht fragen, aber können Sie wissen, wie man das repariert? – Romy

+1

Oh, Sie sollten nicht einen anderen Dialog innerhalb der Aufgabe öffnen, weil es auf einem anderen Thread als ui ausgeführt wird. –

+0

Ah ich verstehe. Die Schaltfläche, die die Verarbeitung startet, öffnet zuerst den OrdnerBrowserDialog, um die Dateien auszuwählen. Soll ich dann die Task.Run-Sache darunter positionieren? – Romy

Verwandte Themen