UI被阻塞,因为您在UI线程上运行登录代码。为了避免这种情况,您可以使用“BackgroundWorker”,或者如果您正在使用4或4.5 .NET,则可以使用“Tasks”将登录内容移动到另一个线程以避免UI阻塞。
如果您正在使用Windows Forms和.NET 4+,请尝试以下方法:
private void button1_Click(object sender, EventArgs e)
{
progressBar1.Visible = true;
Task.Factory.StartNew(Login)
.ContinueWith(t =>
{
progressBar1.Visible = false;
}, TaskScheduler.FromCurrentSynchronizationContext());
}
private static void Login()
{
Thread.Sleep(TimeSpan.FromSeconds(3));
}
它的作用是将登录处理移动到另一个线程,以便UI线程不会被阻塞。在开始登录之前,它会显示进度条,样式设置为marque,在登录完成后,它会再次隐藏进度条。
只要UI没有被阻塞,用户可以在登录期间输入/按下任何他想要的内容,因此解决方案可能是在登录之前禁用所有控件或在单独的模态窗体中显示进度条,这样用户就不会看到应用程序挂起,并且在进度条窗体关闭之前无法进行任何输入。
更新:添加了单独进度窗体的示例。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MarqueeForm.DoWithProgress("Doing login", Login);
}
private static void Login()
{
Thread.Sleep(TimeSpan.FromSeconds(3));
}
}
public class MarqueeForm : Form
{
private Label label;
public MarqueeForm()
{
var progressBar = new ProgressBar
{
Style = ProgressBarStyle.Marquee,
Top = 20,
Size = new Size(300, 15)
};
Controls.Add(progressBar);
label = new Label();
Controls.Add(label);
}
public static void DoWithProgress(string title, Action action)
{
var form = new MarqueeForm
{
Size = new Size(310, 50),
StartPosition = FormStartPosition.CenterParent,
FormBorderStyle = FormBorderStyle.FixedDialog,
ControlBox = false,
label = { Text = title }
};
form.Load += (sender, args) =>
Task.Factory.StartNew(action)
.ContinueWith(t => ((Form)sender).Close(),
TaskScheduler.FromCurrentSynchronizationContext());
form.Show();
}
}