2016-11-28 4 views
2

Ich habe ein Formular mit zwei Tasten (Start, Stop).Abbrechen der Aufgabe in C#

Wenn ich drücke starten Taste eine Aufgabe initialisiert und eine Funktion aufgerufen wird, die am Laufen hält, bis Stopp Taste gedrückt wird.

Aber wenn ich drücke Stop Schaltfläche Form friert ein. Warum? Ich habe Snippet von StackOverflow kopiert, aber es friert immer noch Form ein. So sagen Sie mir, wie Task ordnungsgemäß abgebrochen wird?

public partial class Form1 : Form 
{ 
    private readonly CancellationTokenSource _cts = new CancellationTokenSource(); 
    private Task _task; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    //Funtion that runs when Task is initialized. 
    private void EventLoop(CancellationToken token) 
    { 
     //Code here.. 
     while (!token.IsCancellationRequested) 
     { 
      //Code here.. 
     } 
     if (token.IsCancellationRequested) 
     { 
      MessageBox.Show("Operation Complete..!!"); 
     } 

    } 

    //Function for Start Button. 
    private void Start_Click(object sender, EventArgs e) 
    { 
     _task = Task.Factory.StartNew(() => EventLoop(_cts.Token), _cts.Token); 
    } 

    //Function for Stop button. 
    private void Stop_Click(object sender, EventArgs e) 
    { 
     _cts.Cancel(); 
    } 
} 

ähnliches Beispiel von MSDN:

var compute = Task.Factory.StartNew(() => 
{ 
    return SumRootN(j); 
}, tokenSource.Token);` 

Formular Nach Stopp Taste gedrückt wird. token.IsCancellationRequested ist wahr.

Freeze Form

Voll EventLoop() Funktion.

private void EventLoop(CancellationToken token) 
    { 
     SerialPort sp = new SerialPort(); 
     string text, batch, part, courseName; 
     text = batch = part = courseName = ""; 
     int courseId = 0; 

     this.Invoke((MethodInvoker)delegate() 
     { 
      text = portCB.SelectedItem.ToString(); 
      batch = comboBox2.SelectedItem.ToString(); 
      part = comboBox3.SelectedItem.ToString(); 
      courseName = comboBox1.SelectedItem.ToString(); 
      progressBar1.Value = 20; 
      using (Model1 db = new Model1()) 
      { 
       courseId = db.Courses.Where(c => c.Course_name.ToUpper() == courseName.ToUpper()).Select(c => c.Course_Id).Single(); 
      } 
     }); 

     sp.PortName = text; 
     sp.BaudRate = 9600; 
     sp.Open(); 

     while (!token.IsCancellationRequested) 
     { 
      text = sp.ReadLine(); 

      if (text.Contains("Found ID #")) 
      { 
       this.Invoke((MethodInvoker)delegate() 
       { 
        textBox2.Clear(); 
        textBox2.Text = "Getting Registation ID.\n"; 
        progressBar1.Value = 60; 
       }); 

       string splitText = text.Split('#')[1]; 
       int end = splitText.IndexOf(' '); 
       int id = int.Parse(splitText.Substring(0, end)); 

       using (Model1 db = new Model1()) 
       { 
        var result = db.Students.Where(s => s.Reg_Id == id && s.Batch == batch && s.Class == part).Select(s => s).SingleOrDefault(); 
        if (result != null) 
        { 
         Attendance a = new Attendance(); 
         a.Course_Id = courseId; 
         a.Student_Id = id; 
         a.Status = "P"; 
         a.Date = DateTime.Today.Date; 
         a.Batch = batch; 
         a.Part = part; 

         db.Attendances.Add(a); 
         string message = ""; 

         if (db.SaveChanges() != 0) 
         { 
          message = "Attendance Uploaded..!!\n"; 
         } 
         else 
         { 
          message = "Attendance Not Uploaded ..!!\n"; 
         } 

         this.Invoke((MethodInvoker)delegate() 
         { 
          progressBar1.Value = 100; 
          textBox2.AppendText(message); 
         }); 
        } 
        else 
        { 
         this.BeginInvoke((MethodInvoker)delegate() 
         { 
          textBox2.AppendText("Student Does not belong to Specified Batch Or Part..\n"); 
         }); 
        } 
       } 
      } 
      else 
      { 
       this.Invoke((MethodInvoker)delegate() 
       { 
        textBox2.AppendText("No Match Found..!! \n"); 
       }); 
      } 
      this.Invoke((MethodInvoker)delegate() 
      { 
       textBox1.AppendText(text + "\n"); 
      }); 
     } 
     sp.Close(); 

     // This exception will be handled by the Task 
     // and will not cause the program to crash 
     if (token.IsCancellationRequested) 
     { 
      //MessageBox.Show("Operation Comptele..!!"); 
     } 
    } 
+0

Das ist natürlich sehr, sehr unsauber verwenden, aber Ich sehe nichts, was einen Stillstand verursachen würde. Sicher, Sie registrieren keinen Storno-Callback für das 'CancellationToken' oder rufen' _task.Wait'/'_task.Result' auf? –

+0

Ich mache nichts anderes als Aktivieren und Deaktivieren von CheckBoxen in ** Start ** und ** Stop ** Button Coding .. ich kann es Ihnen zeigen, aber dann wird jeder meine Frage ablehnen .. –

+2

Das Formular im Screenshot ist klar deaktiviert, aber ich sehe nicht, dass die 'Enabled' -Eigenschaft des Formulars irgendwo im Code gesetzt ist, daher denke ich, dass das Problem in dem Teil des Codes auftritt, der nicht gepostet wurde. –

Antwort

3

Sie rufen MessageBox.Show("Operation Complete..!!"); im Verlauf der Stornierung. Dies wird in hohem Maße nicht empfohlen, da nicht davon die Rede ist, dass Sie eine UI-Operation von einem anderen als dem UI-Thread aufrufen.

Kommentar der MessageBox.Show("Operation Complete..!!"); Linie aus

* Edit *

Frage Autor Kommentar zu seiner ursprünglichen Frage, den Fehler gefunden, die Linie aus dem Amt entfernt wurde. Hier ist meine Schlussfolgerung:

immer versuchen ein Problem zu isolieren und in seiner reinsten Form zu reproduzieren. Während dieses Prozesses werden Sie wahrscheinlich die Probleme selbst diagnostizieren und finden :-).

Also wenn der Code mit Problem ist lange zu buchen, es ist definitiv nicht die Art und Weise nur Zeilen löschen dann post es. Die Art und Weise wird Linien zu löschen und sehen, ob das Problem bestehen, mit anderen Worten: Der Isolierung der Ausgabe in seiner reinsten reproduzierbaren Form

+0

Ich habe es kommentiert, aber immer noch gefrieren. –

+0

Könnten Sie bitte den Code innerhalb der while-Schleife posten? –

+0

es ist sehr lang ... und ich will keine negativen Stimmen bekommen, schon am Rande des Verbots. Aber ich werde Risiko eingehen. –

-1

bitte Asynchron-Anruf auf Ihrer Aufgabe

private async void Start_Click(object sender, EventArgs e) 
    { 
     _task = Task.Factory.StartNew(() => EventLoop(_cts.Token), _cts.Token); 
     await task;  
    } 
Verwandte Themen