1

我正在尝试显示从服务器发送到客户端的一些数据。客户端脚本是一个 Windows 窗体应用程序,我有一个名为 label1 的标签,我试图将其文本显示为从服务器客户端接收到的数据,但 label1 的文本根本不会改变。这是什么原因?下面是客户端代码。服务器脚本是一个控制台应用程序。

现在 Program.cs 是空的,Form1.cs 看起来像这样,但 label1.text 仍然出现相同的错误:

namespace WindowsFormsApplication4
{
    public partial class Form1 : Form
    {
        public Form1() { InitializeComponent(); }

        private void Form1_Load(object sender, EventArgs e)
        {
            GetDataFromUDP();
        }

        public static void SetTextForLabel(string myText)
        {

            label1.Text = myText;
        }

        private void GetDataFromUDP()
        {
            UdpClient subscriber = new UdpClient(8899);
            IPAddress addr = IPAddress.Parse("230.0.0.1");
            subscriber.JoinMulticastGroup(addr);
            IPEndPoint ep = null;
            for (int i = 0; i < 10; i++)
            {
                byte[] pdata = subscriber.Receive(ref ep);
                string price = Encoding.ASCII.GetString(pdata);
                //Write data to the label
                SetTextForLabel(price);
            }
            subscriber.DropMulticastGroup(addr);
        }
    }
}

在 SetTextForLabel 里面我得到了错误:

An object reference is required for the non-static field, method, or property 'WindowsFormsApplication4.Form1.label1'



public static void SetTextForLabel(string myText)
{

   label1.Text = myText;
}
4

2 回答 2

0

看起来像一个线程问题。我希望 UDP 调用在池线程的后台运行,这样它就不会阻塞 UI。只需更改获取对象的方法,然后就可以异步调用它。然后我有一个小例程来检查控件是否可以直接更新,否则它只会在主 UI 线程上调用。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        // initialise the ConnectUDP method on a pooled thread
        // Note: could do this from the onLoad event too
        System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(ConnectUDP));

    // This function just invokes the main UI thread if required
    private static void UIThread(Control c, MethodInvoker code)
    {
        if (control.InvokeRequired)
        {
           control.BeginInvoke(code);
           return;
        }
        control.Invoke(code);
    }

    private void ConnectUDP(object obj)
    {
        UdpClient subscriber = new UdpClient(8899);
        IPAddress addr = IPAddress.Parse("230.0.0.1");
        subscriber.JoinMulticastGroup(addr);
        IPEndPoint ep = null;
        for (int i = 0; i < 10; i++)
        {
            byte[] pdata = subscriber.Receive(ref ep);
            string price = Encoding.ASCII.GetString(pdata);
            // Update the label on the main UI thread
            UIThread(label1, delegate {
                label1.Text += price;
            });
        }
        subscriber.DropMulticastGroup(addr);
    }
}
于 2013-07-23T00:30:18.570 回答
0

静态方法SetTextForLabel无权访问类实例的控件Form1Form1您必须通过传递参数或在类中声明静态成员来提供特定实例。

正如评论中提到的,这也不起作用,因为Application.Run()在当前线程中启动了一个应用程序,所以代码也需要一些重构。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        ConnectUDP();
    }

    private void ConnectUDP()
    {
        UdpClient subscriber = new UdpClient(8899);
        IPAddress addr = IPAddress.Parse("230.0.0.1");
        subscriber.JoinMulticastGroup(addr);
        IPEndPoint ep = null;
        for (int i = 0; i < 10; i++)
        {
            byte[] pdata = subscriber.Receive(ref ep);
            string price = Encoding.ASCII.GetString(pdata);
            //Write data to the label
            label1.Text += price;
        }
        subscriber.DropMulticastGroup(addr);
    }
}

然后在Main()

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}
于 2013-07-22T19:32:33.393 回答