是否可以在没有后台工作者的情况下制作一个简单的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;
        }
}

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

您的代码

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所取代。任务具有更多的功能,可以做后台工作人员不能做的事情,而且使用起来更简单。