简体   繁体   中英

Windows Form Application with UDP

I am trying to display some data sent from a Server to client. The Client script is a Windows Form Application and I have a label named label1 whose text I am trying to display as the data received from Server client but label1's text never changes at all. What is the reason for this? Below is the Client side code. The server script is a Console application.

Now Program.cs is empty and Form1.cs looks like this but I still get the same error with the 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);
        }
    }
}

Inside SetTextForLabel I get the error:

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

The static method SetTextForLabel doesn't have access to the controls of the instance of the class Form1 . You have to provide a specific instance by passing a parameter or declaring a static member in the Form1 class.

As mentioned in the comments, this won't work either since Application.Run() starts an application in the current thread so the code needs some refactoring as well.

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

Then in Main() :

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

Looks like a threading issue. I'd want the UDP call to be running in the background on a pooled thread so it doesn't block the UI. Just change the method to take an object and then it can just be called asynchronously. Then I've just got a little routine that checks if the control can be updated directly otherwise it just gets invoked on the main UI thread.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM