我为我的每个网络通信创建一个线程,并且当他们从客户端收到回复时,他们将响应添加到列表中。我正在执行下面的任务以查看是否有任何通信进入。它在屏幕上显示最近的一个。
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# 的新手,所以如果有什么明显的地方请不要犹豫指出。
更新:
根据 sidewinder 链接的 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);
}
}
并通过委托(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]));
});
最佳答案
事件将是一个不错的解决方案。
事件是 Observer 的实现模式,其中源(网络通信)警告观察者(在您的示例中调用任务的人)发生了某些事情。
它的效率要高得多,因为它不会在无限循环中浪费 CPU 使用率,该方法仅在客户端响应时执行。
C# 对事件有很好的支持,考虑阅读 MS Tutorial (最初由 Sidewinder94 发布)。
关于c# - 在 C# 中;从后台线程检查更改的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29976626/