Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C#; what is the most efficent way to check for changes from a background thread?

I create a thread for each of my network communications and they add to a list responses whenever they hear back from a client. I'm starting up the task below at execution to see if any communications come in. It displays the most recent one on screen.

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();

My question is; is there a better way for me to do this? It seems wrong to me to have the task constantly working for something that doesn't happen very often.

Edit: I'm very new to C#, so if there's something obvious please don't hesitate to point it out.

Update:

As per the nice tutorial from MS that sidewinder linked I added a simple event to the Add function of List. as So:

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);
    }
}

and added to my output with a delegate

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]));
                              });
like image 270
Damien Avatar asked Apr 30 '15 19:04

Damien


1 Answers

Events would be a nice solution.

An event is an implementation of the Observer pattern, in which the source (the network communications) warn it's observers(whoever calls the task in your example) that something happened.

It's a lot more efficient since it doesn't waste CPU usage in an infinite loop, the method only executes when a client responds.

C# has a great support for events, consider reading the MS Tutorial(originally posted by Sidewinder94).

like image 118
Genos Avatar answered Sep 19 '22 07:09

Genos