奇怪的标签错误。不会让我设置文本为什么会这样?

时间:2012-02-24 03:53:53

标签: c# winforms label

我从服务器应用程序接收结构,当客户端程序获取它时,它的serverInfo类型将它发送到函数并将服务器信息设置为标签。我已经在两端放置MessageBox.Show()以查看什么是错误的,第一个弹出但第二个没有。第一个消息框显示从服务器收到的结构中的信息,它的全部正确,所以我知道这是有效的。我还在每个label.text =文本之间放了一个消息框,但它们没有显示。我也试过把“这是一个测试字符串”放在他们身上,他们仍然没有做任何事情。

编辑*这是WinForms

编辑*我发现这是一个交叉线程问题,所以有什么方法可以从另一个线程更改标签?

private void onServerInfo(msgBox message)
{
    serverInfo.info info = (serverInfo.info)message.getMessage("info");
    MessageBox.Show(info.name + " ; " + info.type + " ; " + info.limit); // works with everything showing up right
    ServerName.Text = info.name; //this is a string
    ServerType.Text = info.type.ToString(); // this is a enum
    MaxLimit.Text = info.limit.ToString(); // this is a int
    MessageBox.Show(ServerName.Text + " ; " + ServerType.Text + " ; " + MaxLimit.Text); // doesnt ever show
}

2 个答案:

答案 0 :(得分:1)

由于您的异常是由跨线程访问异常引起的,请使用这个方便的方法来解决这个问题:

https://stackoverflow.com/a/2242393/555547

因此,请将您的课程编辑为:

/// <summary>
  /// Extension method that allows for automatic anonymous method invocation.
  /// </summary>
  public static void Invoke(this Control c, MethodInvoker mi)
  {
     c.Invoke(mi);

     return;
  }


private void onServerInfo(msgBox message)
{
this.Invoke
(
   () =>
   {
    serverInfo.info info = (serverInfo.info)message.getMessage("info");
    MessageBox.Show(info.name + " ; " + info.type + " ; " + info.limit); // works with everything showing up right
    ServerName.Text = info.name; //this is a string
    ServerType.Text = info.type.ToString(); // this is a enum
    MaxLimit.Text = info.limit.ToString(); // this is a int
    MessageBox.Show(ServerName.Text + " ; " + ServerType.Text + " ; " + MaxLimit.Text); // doesnt ever show
   }
);
}

虽然为了好的做法,你应该把扩展方法放在它自己的名为ControlExtensions.cs的文件中并从那里调用它。

编辑:实际上,您必须将该扩展方法放入其自己的静态类中,否则您将收到错误。

答案 1 :(得分:1)

首先请允许我向您保证,您所显示的代码片段没有任何问题 - 问题出在其他地方。

事实是你的断点在ServerName.Text行被击中但未在下一行被击中意味着该行会产生异常。

你的应用程序没有粉碎这一事实表明这个异常是在某个地方被默默吞下的,通常不是一件好事和一些使故障排除复杂化的事情(比如你的情况),所以如果这是你可以解决的问题,我会鼓励你这样做。

您可以在Visual Studio中执行的操作之一是进入“调试”菜单并选择“Exceptoins ...”项。出现的对话框将允许您确保调试器也会停止吞下异常,这可能会对情况有所了解,并且可以是一种有用的调试技术。

您需要做的第一件事是找出抛出的异常。这将为您提供新的信息。找到它的一种方法我在上面解释过,但有时候,当有很多异常被抛出并被抓住时,它并不是很实用。在这种情况下,您可以暂时将问题代码包装在try / catch块中,如下所示:

private void onServerInfo(msgBox message)
{
    try 
    {
      serverInfo.info info = (serverInfo.info)message.getMessage("info");
      MessageBox.Show(info.name + " ; " + info.type + " ; " + info.limit); // works with everything showing up right
      ServerName.Text = info.name; //this is a string
      ServerType.Text = info.type.ToString(); // this is a enum
      MaxLimit.Text = info.limit.ToString(); // this is a int
      MessageBox.Show(ServerName.Text + " ; " + ServerType.Text + " ; " + MaxLimit.Text); // doesnt ever show
    }
    catch (Exception ex)
    {
      MessageBox.Show(ex.Message);
    }
}

将您的断点放在MessageBox.Show(ex.Message);上并检查异常的内容。这样您就可以在问题上取得进展。

此时我们可能已经停止了,但让我们想一想可能导致问题的原因。

正如其他人指出的那样,问题很可能是你试图从非UI线程访问UI元素,这是.NET应用程序中不允许的。您可以在此处详细了解How to: Make Thread-Safe Calls to Windows Forms Controls。基本思想是您需要在UI控件上使用InvokeRequired / Invoke方法从另一个线程访问它们。

错误的另一个可能原因可能是,无论出于何种原因,ServerName为空。