是否可以在没有后台工作者的情况下制作一个简单的C#Marquee进度条
本文关键字:一个 简单 C#Marquee 后台 是否 情况下 工作者 | 更新日期: 2023-09-27 18:00:59
我有一个非常简单的表单,上面有一个进度条和一个删除按钮。当用户单击"删除"时,存储过程将运行大约五分钟。
我想运行一个简单的进度条,但它从来没有出现过。我阅读了所有其他关于这方面的问题,但它们都需要一名背景工作者。
有没有可能在没有后台工作人员的情况下制作一个大屏幕进度条?
public partial class ProgressBarSample
{
public ProgressBarSample
{
progressBar1.Style = ProgressBarStyle.Marquee;
progressBar1.Visible = false;
}
private void btnDelete_Click(object sender, EventArgs e)
{
progressBar1.Visible = true;
// run stored procedure that takes around 5 minutes
Task.Delay(10000);
progressBar1.Visible = false;
}
}
您的代码
progressBar1.Visible = true;
// run stored procedure that takes around 5 minutes
Task.Delay(10000);
progressBar1.Visible = false;
阻止应用程序处理windows消息,直到延迟完成,因为您阻止了负责处理这些消息的线程。Windows依赖于及时处理这些邮件。
结果是,您的用户界面将显示为对用户没有响应。
有许多机制允许您在第二个线程上进行处理。BackgroundWorker是WinForms刚问世时常用的一个,现在仍然是一个可靠的选择。您可以使用任何在另一个线程上执行长时间运行的工作的技术,但必须在另一线程上执行。
您可以使用异步模式来简化其他线程的编码
private async void btnDelete_Click(object sender, EventArgs e)
{
progressBar1.Visible = true;
await Task.Run(() =>
{
// run stored procedure that takes around 5 minutes
Task.Delay(10000);
});
progressBar1.Visible = false;
}
如果没有一个可靠地再现问题的好的最小、完整和可验证的代码示例,就不可能确定问题是什么。然而,您发布的代码是不起作用的。btnDelete_Click()
方法将Visible
属性设置为true
,但随后立即将其设置回false
,因为Task.Delay()
方法实际上并不阻塞。
也许你想要的是:
private async void btnDelete_Click(object sender, EventArgs e)
{
progressBar1.Visible = true;
// run stored procedure that takes around 5 minutes
await Task.Delay(10000);
progressBar1.Visible = false;
}
BackgroundWorker是人们普遍接受的进行此类后台工作的方法,因此得名;但是对于一个基元"显示X时间段",你可以使用一个计时器来检查自从(在这种情况下(上次点击删除以来经过的时间量,看看它是否应该隐藏控件(并禁用它自己,当没有事情可做时没有用勾选。(
类似于:
public partial class ProgressBarSample
{
TimeSpan pbShowDuration = [blah blah];
DateTime pbShowFrom = DateTime.MinDate;
public ProgressBarSample
{
progressBar1.Style = ProgressBarStyle.Marquee;
progressBar1.Visible = false;
}
private void btnDelete_Click(object sender, EventArgs e)
{
progressBar1.Visible = true;
pbShowFrom = DateTime.Now;
timer1.Enabled = true;
// run stored procedure that takes around 5 minutes
}
private void timer1_Tick(object sender, EventArgs e)
{
if ((DateTime.Now - pbShowFrom) > pbShowDuration)
{
timer1.Enabled = false;
progressBar1.Visible = false;
}
}
}
但是你打算如何更新进度条?
有了C#中的新任务sync、wait功能,您有了很多选择。如果你不需要做任何事情,只需要让用户知道操作已经完成,你可以启动进度条,然后启动一个运行proc的任务,完成后停止进度条。我个人会放一些进度条以外的东西。对我来说,进度条意味着你有有限的时间等待。如果您的SP可以随时间变化,我会选择某种繁忙显示图标或类似的图标。
在这种情况下,我个人会使用Task.ContinueWith。
MSDN的这篇文章展示了一种很好的处理方法
https://msdn.microsoft.com/en-us/library/dd270696(v=vs.110(.aspx
后台工作者是一种旧方法,已被使用Tasks所取代。任务具有更多的功能,可以做后台工作人员不能做的事情,而且使用起来更简单。