我有一个非常简单的表单,上面有一个进度条和一个删除按钮。当用户单击“删除”时,存储过程将运行大约五分钟。
我想要一个简单的选框进度条来运行,但它永远不会出现。我阅读了有关此问题的所有其他问题,但他们都需要一名后台工作人员。
是否可以在没有后台工作者的情况下制作选框进度条?
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;
}
}
答案 0 :(得分:1)
您的代码
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;
}
答案 1 :(得分:1)
如果没有能够可靠地再现您的问题的好Minimal, Complete, and Verifiable code example,就无法确定问题是什么。但是,您发布的代码无法正常运行。您的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;
}
答案 2 :(得分:0)
BackgroundWorker是进行此类背景工作的普遍接受的方法,因此得名;但是对于X时段"的原始"显示,你可以使用一个Timer来检查自上次点击删除以来(或在这种情况下)删除的时间,以查看它是否应该隐藏控件(和禁用它自己,当没有任何事情要做时,不要使用滴答声。)
类似的东西:
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;
}
}
}
但您打算如何更新进度条?
答案 3 :(得分:0)
使用新任务,同步,等待C#中的功能,您有很多选择。如果除了让用户知道操作已完成之外你不需要做任何事情,你可以启动进度条,然后启动一个运行你的proc的任务,当它完成后停止进度条。我个人会提出一个进度条以外的东西。对我而言,进度条意味着您有一段有限的时间等待。如果您的SP可以随时间变化,我会使用某种繁忙的显示图标或类似的东西。
在这种情况下,我个人会使用Task.ContinueWith。
这篇MSDN文章展示了处理它的好方法。
https://msdn.microsoft.com/en-us/library/dd270696(v=vs.110).aspx
答案 4 :(得分:0)
后台工作程序是一种旧方法,它被使用任务取代。任务具有更多功能,可以做背景工作者无法做到的事情,并且使用起来更简单。