尝试连接服务器时显示“正在加载”动画
本文关键字:加载 正在加载 动画 连接 服务器 显示 | 更新日期: 2023-09-27 17:59:24
我有一个简单的登录表单,它连接到服务器。
当用户按下登录按钮时,需要显示动画加载GIF,直到连接成功或失败。
理论上,我做到了:
private void button_login_Click(object sender, EventArgs e)
{
button_login.Text = WORKING;
Loading(ShowMode.show, pictureBox_login_loading);
// send request
client = new TcpClient();
try
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);
client.Connect(endPoint);
// send login details .. :)
output = client.GetStream();
writer = new BinaryWriter(output);
reader = new BinaryReader(output);
// write details
writer.Write("login" "|" userID "|" privateName);
}
catch (Exception)
{
MessageBox.Show("Server is down.");
return;
}
finally
{
// Stop loading and return status
button_login.Text = DEFAULT_LOGIN_TEXT;
Loading(ShowMode.hide, pictureBox_login_loading);
}
}
Loading是一个将PictureBox的Visible属性设置为Visible
的函数。(我以为会有帮助)
问题是:gif只有在button_login_Click
运行完之后才可见,而在它不可见之后才可见。
如何使动画gif在执行的行上可见?
问题是您没有向GUI线程让步,因此无法显示GIF。
我建议使用BackgroundWorker连接到您的客户端,然后在Worker的已完成调用中开始工作并停止工作之前显示GIF。
示例代码(注意,我没有编译这个,因为我没有足够的源代码):
button_login.Text = WORKING;
Loading(ShowMode.show, pictureBox_login_loading);
// send request
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler((obj, args) =>
{
client = new TcpClient();
try
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);
client.Connect(endPoint);
// send login details .. :)
output = client.GetStream();
writer = new BinaryWriter(output);
reader = new BinaryReader(output);
// write details
writer.Write("login" "|" userID "|" privateName);
}
catch (Exception)
{
this.Invoke(new Action(() =>MessageBox.Show("Server is down."));
}
});
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler((obj, args) =>
{
button_login.Text = DEFAULT_LOGIN_TEXT;
Loading(ShowMode.hide, pictureBox_login,loading);
});
worker.RunWorkerAsync();
这种方法屈服于GUI线程,允许它显示您的GIF,并且仍然监视您的连接,并在完成时删除GIF和恢复按钮文本。
由于这是一个你想要的动画,你可能需要在另一个线程上启动连接,这样UI线程就不会被阻塞。如果它是一个静态图像,您可以调用picturebox的Update()
方法来显示它。但对于你的情况,这样的东西应该有效:
Thread thread = new Thread(new ThreadStart(delegate
{
Invoke((Action)(()=>{ button_login.Text = WORKING; Loading(ShowMode.show, pictureBox_login_loading); }));
// send request
client = new TcpClient();
try
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);
client.Connect(endPoint);
// send login details .. :)
output = client.GetStream();
writer = new BinaryWriter(output);
reader = new BinaryReader(output);
// write details
writer.Write("login" "|" userID "|" privateName);
}
catch (Exception)
{
MessageBox.Show("Server is down.");
return;
}
finally
{
// Stop loading and return status
Invoke((Action)(()=>{ button_login.Text = DEFAULT_LOGIN_TEXT; Loading(ShowMode.hide, pictureBox_login_loading); }));
}
}));
thread.Start();
你也可以像讨论的另一个答案一样使用BackgroundWorker,但我倾向于将它们保留用于更长时间运行的任务,比如用进度条报告进度的任务。如果它是一个短(ish)任务,我通常在中使用Thread
或Task.Factory.StartNew
。NET 4.0。