是否可以在没有后台工作者的情况下创建一个简单的C#Marquee进度条?

时间:2016-08-05 17:58:09

标签: c# .net progress-bar

我有一个非常简单的表单,上面有一个进度条和一个删除按钮。当用户单击“删除”时,存储过程将运行大约五分钟。

我想要一个简单的选框进度条来运行,但它永远不会出现。我阅读了有关此问题的所有其他问题,但他们都需要一名后台工作人员。

是否可以在没有后台工作者的情况下制作选框进度条?

    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;
        }
}

5 个答案:

答案 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)

后台工作程序是一种旧方法,它被使用任务取代。任务具有更多功能,可以做背景工作者无法做到的事情,并且使用起来更简单。