直到代码执行完毕,标签才会改变颜色

本文关键字:标签 改变 变颜色 代码 执行 | 更新日期: 2023-09-27 18:04:29

有很多不相关的代码需要浏览。但是基本上它发送一个数据包然后监听返回的数据包

如果我注释掉在发送包结束时调用ReceiveAuthPacket()方法的部分,它将工作并且标签将变成蓝色。但否则它将永远不会激活将标签变为蓝色,而是将标签变为红色或绿色(取决于返回的数据包)。

基本上我只是用标签作为状态的指示器。不管我怎么尝试,我都不能让它变成蓝色,因为它似乎在等待所有的代码完成执行,它就是不工作。

我甚至尝试在WPF中使用数据触发器,但它仍然不起作用。

有什么办法吗?我就是不明白…

        private readonly UdpMessageAuthentication _msgAuth;        
        private void Button_Authenticate_OnClick(object sender, RoutedEventArgs e)
        {
            Label_Authentication.Content = "Attempting Authentication";
            Label_Authentication.Foreground = new SolidColorBrush(Colors.Blue);
            _msgAuth.SendAuthPacket(IPAddress.Parse(TextBox_IP.Text), TextBox_ClientID.Text);
        }
        public void SendAuthPacket(IPAddress ip, string userID)
        {
            _ip = ip;
            _userID = userID;
            if (_udpClient.Client == null)
                _udpClient = new UdpClient();
            //GSISClockRegRequest,<Client Id>,,1 
            string msg = string.Format("GSISClockRegRequest,{0},,1", _userID);
            byte[] sendBytes = Encoding.ASCII.GetBytes(msg);
            bool sent = false;
            try
            {
                _label.Content = "Attempting Authentication";
                _label.Foreground = new SolidColorBrush(Colors.Blue);
                while (_label.Content != "Attempting Authentication")
                {
                    //loop
                }
                _udpClient.Connect(_ip, 5001);
                _udpClient.Send(sendBytes, sendBytes.Length);
                Console.WriteLine("Sending {0} bytes.  Message: {1}", sendBytes.Length, msg);
                sent = true;
            }
            catch (Exception)
            {
                Console.WriteLine("UDP Auth Packet Failed to Send");
            }
            _udpClient.Close();
            if (sent)
                ReceiveAuthPacket();  //IF I COMMENT THIS OUT IT'LL WORK
        }
        private void ReceiveAuthPacket()
        {
            IPEndPoint e = new IPEndPoint(IPAddress.Any, 5001);
            UdpClient u = new UdpClient(e);
            u.Client.ReceiveTimeout = 3000;
            Console.WriteLine("Listening for Messages: ");
            try
            {
                Byte[] receiveBytes = u.Receive(ref e);
                string receiveString = Encoding.ASCII.GetString(receiveBytes);
                Console.WriteLine("Received: {0}", receiveString);
                string errMsg = "";
                if (AuthMessageParser.ParseMessage(receiveString, ref errMsg))
                {
                    _label.Content = "Authentication Successful!";
                    _label.Foreground = new SolidColorBrush(Colors.Green);
                }
                else
                {
                    _label.Content = "Authentication Unsuccessful: " + errMsg;
                    _label.Foreground = new SolidColorBrush(Colors.Red);
                }
            }
            catch (Exception)
            {
                _label.Content = "Authentication Unsuccessful";
                _label.Foreground = new SolidColorBrush(Colors.Red);
                Console.WriteLine("UDP Auth Packet was NOT Received.");
            }
            u.Close();
        }

直到代码执行完毕,标签才会改变颜色

你的UI线程被诸如_udpClient.Connect()_udpClient.Send()(以及接收)的调用阻塞

一种解决方法是利用任务并行库并异步执行通信,以避免阻塞UI线程。

只要你正确定义任务,它就会为你管理线程。如果你需要一个例子,就喊一声。

protected void SomeButton_Click(Object sender, EventArgs e)
{
    // Task off the work and do not wait, no blocking here.
    Task.Run(PerformConnection);
}
private async Task PerformConnection()
{
    // This method acts the way a thread should.  We await the result of async comms.
    // This will not block the UI but also may or may not run on its own thread.
    // You don't need to care about the threading much.
    var conn = await ListenerOrSomething.AwaitConnectionsAsync( /* ... */ );
    // Now you have your result because it awaited.
    using(var newClient = conn.Client())
    {
        var buffer = new byte[];           
        var recv = await newClient.ReceiveAsyncOrSomething(out buffer);
        // Data received is not zero, process it or return
        if(recv > 0)
            newClient.Response = await ProcessRequest(buffer);
        else
            return;
    }
}