2015-04-30 19 views
5

Ich erstelle einen Thread für jede meiner Netzwerkkommunikationen und sie fügen zu einer Liste Antworten hinzu, wann immer sie von einem Client zurückkommen. Ich beginne die unten stehende Aufgabe bei der Ausführung, um zu sehen, ob irgendeine Kommunikation hereinkommt. Sie zeigt die neueste auf dem Bildschirm an.In C#; Was ist der effizienteste Weg, um nach Änderungen aus einem Hintergrundthread zu suchen?

Task task = new Task(
(() => 
{ 
    int i = 0; 
    while (true) 
    { 
     if (responses.Count > i){ 
      Debug.WriteLine(responses[i]); 
      int index = Form.ActiveForm.Controls.IndexOfKey("responseBox"); 
      Form.ActiveForm.Invoke((MethodInvoker) (() => Form.ActiveForm.Controls[index].Visible = true)); 
      Form.ActiveForm.Invoke((MethodInvoker) (() => Form.ActiveForm.Controls[index].Text = responses[i])); 
      i++; 
     } 
    } 
})); 
task.Start(); 

Meine Frage ist; Gibt es einen besseren Weg für mich, dies zu tun? Es scheint mir falsch, die Aufgabe ständig für etwas zu haben, was nicht oft passiert.

Edit: Ich bin sehr neu in C#, also wenn es etwas offensichtlich ist, zögern Sie bitte nicht, darauf hinzuweisen.

Update:

Gemäß dem netten Tutorial von MS, dass Klapperschlange verknüpfen ich ein einfaches Ereignis an die Add-Funktion der Liste hinzugefügt. So wie:

public delegate void ChangedEventHandler(object sender, EventArgs e); 

public class listWithChanges<T> : List<T> 
{ 
    public event ChangedEventHandler Changed; 

    protected virtual void OnChanged(EventArgs e) 
    { 
     if (Changed != null) 
      Changed(this, e); 
    } 

    public new void Add (T item) 
    { 
     base.Add(item); 
     OnChanged(EventArgs.Empty); 
    } 
} 

und zu meiner Ausgabe mit einem Delegierten

responses.Changed += ((o, e) => { 
           int index = Form.ActiveForm.Controls.IndexOfKey("responseBox"); 
           Form.ActiveForm.Invoke((MethodInvoker) (() => Form.ActiveForm.Controls[index].Visible = true)); 
           Form.ActiveForm.Invoke((MethodInvoker) (() => Form.ActiveForm.Controls[index].Text = responses[responses.Count - 1])); 
           }); 
+2

, warum Sie nicht nur Ereignisse auslösen? –

+2

weil ich neu in C# bin und keine Ahnung habe, was du meinst :) – Damien

+1

Ereignisse sind der Weg in C# für diese Art von Aktion, wenn du ein Tutorial brauchst, um hier anzufangen ist das von MS: https: //msdn.microsoft.com/en-us/library/aa645739(v=vs.71).aspx – Sidewinder94

Antwort

4

Ereignisse wäre eine schöne Lösung sein.

Ein Ereignis ist eine Implementierung des Observer Musters, in dem die Quelle (die Netzwerkkommunikation) ihre Beobachter warnt (wer auch immer die Aufgabe in Ihrem Beispiel aufruft), dass etwas passiert ist.

Es ist viel effizienter, da es keine CPU-Auslastung in einer Endlosschleife verschwendet, die Methode wird nur ausgeführt, wenn ein Client antwortet.

C# hat eine große Unterstützung für Ereignisse, lesen Sie die MS Tutorial (ursprünglich von Sidewinder94 veröffentlicht).

2

Wenn Sie durch große Umstrukturierung des Codes gehen nicht haben wollen, können Sie eine Warteschlange blockieren können für Ihre responses Sammlung, so dass Ihre Lese Thread blockiert, während für ein Element wartet in der Warteschlange angezeigt werden .

Warten, bis etwas in einer blockierenden Warteschlange angezeigt wird, verbraucht keine CPU.

eine schnelle Suche Ausbeuten dieses (Technisch nicht Null ist, aber dennoch nicht wahrnehmbar.): MSDN - BlockingCollection Class

Verwandte Themen