在 C# 中;从后台线程检查更改的最有效方法是什么?

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

我为我的每个网络通信创建了一个线程,每当他们收到来自客户端的回复时,他们就会将响应添加到列表中。我正在执行下面的任务以查看是否有任何通信进来。它在屏幕上显示最近的一个。

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

我的问题是;我有更好的方法吗?让任务不断地为不经常发生的事情工作对我来说似乎是错误的。

编辑:我是 C# 的新手,所以如果有什么明显的地方请毫不犹豫地指出来。

更新:

根据响尾蛇链接的 MS 的精彩教程,我向列表的添加功能添加了一个简单的事件。所以:

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

并通过委托添加到我的输出中

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

事件将是一个很好的解决方案。

事件是 Observer 模式的实现,其中源(网络通信)警告它的观察者(在您的示例中调用任务的任何人)发生了什么事。

效率高得多,因为它不会在无限循环中浪费 CPU 用法,该方法仅在客户端响应时执行。

C# 对事件有很好的支持,考虑阅读 MS Tutorial(最初由 Sidewinder94 发布)。

如果您不想对代码进行重大重构,可以为您的 responses 集合使用 阻塞队列,这样您的在等待项目出现在队列中时读取线程块。

等待某个东西出现在阻塞队列中消耗零 CPU。 (技术上不为零,但仍然不明显。)

快速搜索得到:MSDN - BlockingCollection Class