Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过进度条显示执行进度_C#_.net_Stored Procedures_Progress Bar_Backgroundworker - Fatal编程技术网

C# 通过进度条显示执行进度

C# 通过进度条显示执行进度,c#,.net,stored-procedures,progress-bar,backgroundworker,C#,.net,Stored Procedures,Progress Bar,Backgroundworker,我有一个愚蠢的问题,但我被卡住了。我正在从代码中执行一个存储过程 过程需要时间,所以为此我显示了一个进度条,它显示了执行的进度,但是存储过程执行了,并且没有任何东西需要我增加进度条的值 这是我的密码 void btnYes_Click(object sender, EventArgs e) { if (DialogResult.Yes == MessageBox.Show("Are you sure", "", MessageBoxButtons.YesNo)) {

我有一个愚蠢的问题,但我被卡住了。我正在从代码中执行一个存储过程 过程需要时间,所以为此我显示了一个进度条,它显示了执行的进度,但是存储过程执行了,并且没有任何东西需要我增加进度条的值

这是我的密码

void btnYes_Click(object sender, EventArgs e)
{
   if (DialogResult.Yes == MessageBox.Show("Are you sure", "", MessageBoxButtons.YesNo))
    {
        try
        {
         dbDataEntities db = new dbDataEntities();
        string myquery = "DECLARE @return_value int EXEC    @return_value = [dbo].[ssspUpdateMarksOfStudent] SELECT 'Return Value' = @return_value";
         //progressbar1.Maximum = 5000; 
         //progressbar1.value = ?; // how could i increment it
         //
         db.Database.ExecuteSqlCommand("myquery");



        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}
此外,我还尝试通过设置当前值来使用秒表,该值在执行过程时不会增加

Stopwatch st = new Stopwatch();
st.Start();
progressbar1.Maximum = 5000; 
progressbar1.Value = Convert.ToInt16(st.Elapsed.Seconds);
//My stored procedure call 
st.Stop(); 
那么,这只能通过使用
后台工作者来完成,还是有其他方法来完成

我是编程新手,所以没有太多地使用
后台工作者
,所以我正在尝试寻找替代方案


请建议。提前感谢。

存储过程不提供进度信息。您可以使用
Marquee
样式设置中的
ProgressBar
来设置一个有趣的想法
SqlConnection
提供
InfoMessage
事件,当服务器执行
PRINT
命令时触发该事件。您可以打印存储过程的某些部分并侦听此事件

——做点什么
打印“完成10%”;
--做另一件事
打印“完成20%”;
...
打印“100%完成”;
除此之外,使用@hamlet hakobyan的解决方案。只需显示一个无限的进度条


更新:更新为包含完整的解决方案 首先,我讨厌给出完整的答案。它阻碍了大脑找到解决方案的能力。相反,我喜欢把人们推到正确的道路上,这样他们就可以走这条路了。 但无论如何,它在这里。在W7x64SP1和SQL2012下使用VS2012、NET4、MSIL进行测试

我非常耗时的SP使用
RaisError
而不是
Print
立即发送消息。


看起来您正在gui线程上运行存储过程

这意味着您的应用程序将在调用运行时失去响应,因为消息泵被阻塞。那可能是个坏主意。我建议将所有长时间运行的调用转移到另一个线程

Background Worker是一个设计用于报告长时间运行的任务进展情况的类,这样您就可以更新UI,但是由于您的任务只是一个项目,没有太多需要报告的内容,因此它可能不是您的正确选择

也许你想要某种形式的东西(猜测语法,因为我手头没有编译器)和借鉴


我研究了背景工作者,我是这样做的 我将程序的执行放在另一个线程上,并将进度条放在GUI线程中

 BackgroundWorker bg = new BackgroundWorker();
 Boolean stopwork = true;
 Private void btnYes_Click(object sender, EventArgs e)
        {
            if (DialogResult.Yes == MessageBox.Show(clsGlobalObjectRefrances.OMessageString.SureWant2UpdateMarks, "", MessageBoxButtons.YesNo))
            {
                try
                {

                    bg.DoWork += bg_DoWork;
                    bg.RunWorkerCompleted += bg_RunWorkerCompleted;
                    bg.RunWorkerAsync();
                    pgbUpdateMarks.Maximum = 60;
                    Stopwatch st = new Stopwatch();
                    st.Start();
                    while(stopwork)
                    {
                        pgbUpdateMarks.Value = st.Elapsed.Seconds;
                    }
                    pgbUpdateMarks.Value = 0;
                    MessageBox.Show("Executed sucessfully");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
嫁妆在哪里

 void bg_DoWork(object sender, DoWorkEventArgs e)
        {

        dbDataEntities db = new dbDataEntities();
        string myquery = "DECLARE @return_value int EXEC    @return_value = [dbo].[ssspUpdateMarksOfStudent] SELECT 'Return Value' = @return_value";
        db.Database.ExecuteSqlCommand("myquery");
        stopwork = false;
        }

请遵循这个方法

  • 首先计算执行存储过程的时间。
    db.Database.ExecuteSqlCommand(“myquery”)
    在这里输入代码

  • 为执行此查询分配单独的线程/(进程的一部分)。使用c#中的后台工作控件(在do#u工作事件中)

  • 类似地,使用后台工作程序分配一个单独的进程线程,用于显示进度条状态。(正在进行更改事件)只需将值增加10%。稍微休息一下(根据使用查询的时间将其分为十个部分)。 完成时生成Progressbar.value=100(运行中的Worker CompletedEvent

  • 请同时调用两个线程
    backgroundWorker1.RunWorkerAsync()

    我认为这解决了你的问题



    您可以考虑优化存储过程优化存储过程??我的意思是,有没有一种方法可以让存储过程运行得更快—解决根本问题。也许这是不可能的,但可能值得检查。例如,您可以向数据库添加一些索引,使其运行更快。虽然问题不在我的存储过程中,但很难说没有看到它。。问题是我无法通过进度显示执行进度。存储过程中是否有迭代?是否有可能从SP中删除带有整数值的select?是否有方法使用BackgroundWorker的
    ReportProgress
    ProgressChanged
    方法来增加常规进度条?是的,如果长时间运行的任务中有报告进度的地方,您可以在工作线程上调用ReportProgress,而ProgressChanged事件将在UI线程上触发。我认为您可能需要明确启用它。阅读“后台工作人员”可以向您展示如何操作的文档:当您可以使用任务时,没有理由使用BackgroundWorker。它不提供Task.Run/IProgress的任何组合,虽然它需要更多的代码,但更重,除了一个简单的数字,它不能提供任何进展Tanks@PanagiotisKanavos我没有注意到新的IProgress界面,这看起来比后台工作程序干净得多。在.NET3.5之前,这可能是一个可以接受的解决方案,但不是很好的解决方案。NET4允许您以更简单的方式执行相同的操作。你本可以在6行中完成同样的事情。顺便说一句,你调用程序的方式不仅是错误的,而且是危险的。只需创建一个具有StoredProcedure类型的DbCommand并传递参数。如何在执行代码时显示存储过程的状态。。因为在过程执行时UI被卡住UI被卡住是因为您使用了
    BackgroundWorker
    错误。在调用
    RunWorkerAsync
    之后,您仍然会运行代码,直到worker完成。您应该创建另一个计时器来更新进度条,并使用
    RunWorkerCompleted
    来跟踪完成情况。正如我在问题中提到的,我没有使用后台工作程序,因此如果不使用它,Ui就会卡住
    progressbar1.Style = ProgressBarStyle.Marquee; //thanks Hamlet
    progressbar1.MarqueeAnimationSpeed = 30;
    
    //run the long running thing on a background thread.
    var bgTask = Task.Factory.StartNew(() => db.Database.ExecuteSqlCommand("myquery"));
    
    //when it's done, back on this thread, let me know and we'll turn the progress bar off
    bgTask.ContinueWith(resultTask => {
        progressBar1.Style = ProgressBarStyle.Continuous;
        progressBar1.MarqueeAnimationSpeed = 0;
     }, TaskScheduler.FromCurrentSynchronizationContext());
    
     BackgroundWorker bg = new BackgroundWorker();
     Boolean stopwork = true;
     Private void btnYes_Click(object sender, EventArgs e)
            {
                if (DialogResult.Yes == MessageBox.Show(clsGlobalObjectRefrances.OMessageString.SureWant2UpdateMarks, "", MessageBoxButtons.YesNo))
                {
                    try
                    {
    
                        bg.DoWork += bg_DoWork;
                        bg.RunWorkerCompleted += bg_RunWorkerCompleted;
                        bg.RunWorkerAsync();
                        pgbUpdateMarks.Maximum = 60;
                        Stopwatch st = new Stopwatch();
                        st.Start();
                        while(stopwork)
                        {
                            pgbUpdateMarks.Value = st.Elapsed.Seconds;
                        }
                        pgbUpdateMarks.Value = 0;
                        MessageBox.Show("Executed sucessfully");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
            }
    
     void bg_DoWork(object sender, DoWorkEventArgs e)
            {
    
            dbDataEntities db = new dbDataEntities();
            string myquery = "DECLARE @return_value int EXEC    @return_value = [dbo].[ssspUpdateMarksOfStudent] SELECT 'Return Value' = @return_value";
            db.Database.ExecuteSqlCommand("myquery");
            stopwork = false;
            }