1

所以我正在处理一个自动更新服务器列表,它加载所有服务器 ip:port 组合并将它们显示到列表视图中。我在一个线程中执行所有这些操作,因此我需要调用我的控件来对它们执行操作。这是我的调用方法..

    public void invoke(MethodInvoker m) {
        try { invoke(m); } catch {} 
    }

这是我的更新线程方法:

    public void updater()
    {
        while (autoUpdate)
        {
            reader = new StreamReader("servers.list");
            servers = reader.ReadToEnd().Split('\n');
            reader.Close();

            invoke(new MethodInvoker(delegate { list.Clear(); }));

            foreach (String s in servers)
            {
                String[] part = new String[] { s };
                invoke(new MethodInvoker(delegate { list.Items.Add("Server Name").SubItems.AddRange(part); }));
            }

            Thread.Sleep(5000);
        }
    }

有谁知道它为什么这样做?我以前做过这样的应用程序,没有遇到过这个问题。也许我错过了一些东西,但任何帮助将不胜感激。

谢谢。

4

3 回答 3

4

这看起来像一个无限递归调用,缺少结束条件?

public void invoke(MethodInvoker m) 
{
   try { invoke(m); } catch {} 
}
于 2012-07-18T06:45:37.383 回答
2

您需要将其更改为:

public void invoke(MethodInvoker m) 
{
   try { someControl.Invoke(m); } catch {} 
}
于 2012-07-18T06:49:21.577 回答
1

您的invoke方法在没有终止条件的情况下递归调用自身。您需要做的是检查控件是否要求在 UI 线程上分派操作,并适当地重新调用该方法。

您应该Invoke在同一线程上创建的某个控件上使用该方法(这可能是要更新的控件,也可能是父窗体;这并不重要):

public void invoke(MethodInvoker m) 
{
   try { this.Invoke(m); } catch {} 
}

不过,附带说明一下,像这样有一个空的雨伞catch块是非常糟糕的做法。这样做你基本上忽略了任何可能发生的错误,无论它是否可以/应该被忽略。您应该只尝试捕获您知道如何处理的异常;否则,让它传播回堆栈到一些可以处理它的代码。

于 2012-07-18T06:47:17.433 回答