在做一个简单地winform工控机,主要使用TCP连接。但不知道为说明在调用delegate时会产生错序的情况。
我在主界面上面设置了一个Status Strip来作为状态提示。然后在全局变量中声明委托,这样我就可以在异步创建Tcp连接时去更新主界面的状态提示。
namespace RsmiMonitorForWifi
{
///全局delegate
public delegate void StatusUpdate(string infor);
internal static class Program
{
///
/// 应用程序的主入口点。
///
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmModelSelect());
}
}
}
frmMain.cs(1/2)
public static StatusUpdate statusUpdate = null;
public frmMain()
{
InitializeComponent();
statusUpdate = new StatusUpdate(StatusUpdate);
tcpMethod = new tcpMethod("192.168.1.39",8080);
TcpClient tcpClient = tcpMethod.TcpCreateAsync();
}
TcpMethod.cs
public TcpClient TcpCreateAsync()
{
tcpClient = new TcpClient();
try
{
tcpClient.BeginConnect(iP, iPort, new AsyncCallback(ConnectedAsync), tcpClient);
_tcpBusy = true;
frmMain.statusUpdate("正在尝试连接网络...");
}
catch (Exception e)
{
frmMain.statusUpdate(e.Message);
}
return tcpClient;
}
//连接回调
private void ConnectedAsync(IAsyncResult asyncResult)
{
tcpClient = asyncResult.AsyncState as TcpClient;
if (tcpClient != null)
{
try
{
tcpClient.EndConnect(asyncResult);
frmMain.statusUpdate("连接成功");
}
catch (SocketException e)
{
frmMain.statusUpdate(e.Message);
}
}
_tcpBusy = false;
}
问题出在下面这一段,因为发现单个statuslabel的显示效果不好,我想要让statuslabel1储存statuslabel2的内容,用stauslabel2去显示最新的状态信息,如图:
frmMain.cs(2/2)
private void StatusUpdate(string infor)
{
string currentTime = DateTime.Now.ToString("HH:mm:ss");
//不知道为什么delegate的调用顺序会出问题,暂时只使用一个text
//statuslb_currentstate1.Text = statuslb_currentstate2.Text;
statuslb_currentstate2.Text = $"{currentTime} {infor}";
}
测试下来在第一次连接时表现良好,但当我第二次创建连接时,理论上应该更新两次时实际只更新了一次,表现正常的情况下label1的text应为11:08分的 "正在尝试连接", label2的text应为11:08分后的 "连接成功"
Debug后发现主页面更新时,先更新了"连接成功"
然后label1的text没有被更新,紧接着label2的值被更新成 "正在尝试连接",造成了看上去只有label2被更新了一次的假象。
之后我发现debug时情况会有所不同,有时可以又是不行。我的猜测是我对线程运作的理解有误,导致主线程更新控件时的执行顺序随机。怎么样才能稳定的实现我想要的效果呢