如何在 Windows Forms C# 中执行代码时显示动画加载表单
How to show an animated loading form while executing code in Windows Forms C#
我想在主窗体中执行一些代码时显示动画加载窗体。动画形式仅用于向用户显示操作正在执行,我想在操作完成后关闭它。我使用的代码是:
public partial class Form_main_admin : Form
{
private Thread loadingThread;
private string loadingText;
public Form_main_admin()
{
InitializeComponent();
}
private void main_tabControl_SelectedIndexChanged(object sender, EventArgs e)
{
switch (main_tabControl.SelectedIndex)
{
case 0:
// ...
break;
case 1:
showLoadingForm("Loading");
// Load a datagridview (load data, adjust column widths) in Form_main_admin
closeLoadingForm();
break;
}
}
private void showLoadingForm(string text)
{
loadingText = text;
loadingThread = new Thread(new ThreadStart(openLoadingForm));
loadingThread.Start();
}
private void openLoadingForm()
{
try
{
Form_loading loadingForm = new Form_loading(loadingText);
loadingForm.ShowDialog();
}
catch
{
Thread.ResetAbort();
}
}
private void closeLoadingForm()
{
try
{
loadingThread.Abort();
}
catch
{
Thread.ResetAbort();
}
}
}
问题是当我在选项卡之间快速切换时出现 "Thread was being aborted" 异常(请参见下面 link 中的图像)。
http://postimg.org/image/bvre2bmi5/
我不希望用户切换标签太快时看到此异常。在阅读了该论坛上的其他帖子后,我意识到不推荐我的实现。有人可以告诉我如何正确实现此功能吗?
如果您需要动画进度表,请尝试使用 BackgroundWorker class 在附加线程中执行加载:
public partial class MainForm : Form
{
/// <summary>
/// Some progress form
/// </summary>
WaitForm waitForm = new WaitForm();
/// <summary>
/// https://msdn.microsoft.com/library/cc221403(v=vs.95).aspx
/// </summary>
BackgroundWorker worker = new BackgroundWorker();
public MainForm()
{
InitializeComponent();
worker.DoWork += (sender, args) => PerformReading();
worker.RunWorkerCompleted += (sender, args) => ReadingCompleted();
}
/// <summary>
/// This method will be executed in an additional thread
/// </summary>
void PerformReading()
{
//some long operation here
Thread.Sleep(5000);
}
/// <summary>
/// This method will be executed in a main thread after BackgroundWorker has finished
/// </summary>
void ReadingCompleted()
{
waitForm.Close();
}
private void button1_Click(object sender, EventArgs e)
{
//Run reading in an additional thread
worker.RunWorkerAsync();
//Show progress form in a main thread
waitForm.ShowDialog();
}
}
我想在主窗体中执行一些代码时显示动画加载窗体。动画形式仅用于向用户显示操作正在执行,我想在操作完成后关闭它。我使用的代码是:
public partial class Form_main_admin : Form
{
private Thread loadingThread;
private string loadingText;
public Form_main_admin()
{
InitializeComponent();
}
private void main_tabControl_SelectedIndexChanged(object sender, EventArgs e)
{
switch (main_tabControl.SelectedIndex)
{
case 0:
// ...
break;
case 1:
showLoadingForm("Loading");
// Load a datagridview (load data, adjust column widths) in Form_main_admin
closeLoadingForm();
break;
}
}
private void showLoadingForm(string text)
{
loadingText = text;
loadingThread = new Thread(new ThreadStart(openLoadingForm));
loadingThread.Start();
}
private void openLoadingForm()
{
try
{
Form_loading loadingForm = new Form_loading(loadingText);
loadingForm.ShowDialog();
}
catch
{
Thread.ResetAbort();
}
}
private void closeLoadingForm()
{
try
{
loadingThread.Abort();
}
catch
{
Thread.ResetAbort();
}
}
}
问题是当我在选项卡之间快速切换时出现 "Thread was being aborted" 异常(请参见下面 link 中的图像)。
http://postimg.org/image/bvre2bmi5/
我不希望用户切换标签太快时看到此异常。在阅读了该论坛上的其他帖子后,我意识到不推荐我的实现。有人可以告诉我如何正确实现此功能吗?
如果您需要动画进度表,请尝试使用 BackgroundWorker class 在附加线程中执行加载:
public partial class MainForm : Form
{
/// <summary>
/// Some progress form
/// </summary>
WaitForm waitForm = new WaitForm();
/// <summary>
/// https://msdn.microsoft.com/library/cc221403(v=vs.95).aspx
/// </summary>
BackgroundWorker worker = new BackgroundWorker();
public MainForm()
{
InitializeComponent();
worker.DoWork += (sender, args) => PerformReading();
worker.RunWorkerCompleted += (sender, args) => ReadingCompleted();
}
/// <summary>
/// This method will be executed in an additional thread
/// </summary>
void PerformReading()
{
//some long operation here
Thread.Sleep(5000);
}
/// <summary>
/// This method will be executed in a main thread after BackgroundWorker has finished
/// </summary>
void ReadingCompleted()
{
waitForm.Close();
}
private void button1_Click(object sender, EventArgs e)
{
//Run reading in an additional thread
worker.RunWorkerAsync();
//Show progress form in a main thread
waitForm.ShowDialog();
}
}