在代码执行完毕之前,Label不会更改颜色

时间:2014-05-20 16:56:44

标签: c# .net wpf

要查看很多不相关的代码..但几乎它发送数据包并侦听数据包作为回报

如果我在发送数据包结束时对其调用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();
        }

1 个答案:

答案 0 :(得分:3)

通过调用_udpClient.Connect()_udpClient.Send()(以及收件人)等内容阻止了您的UI线程

解决方法是利用任务并行库并异步执行通信,以避免阻塞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;
    }
}