C#在执行阻塞进程之前执行GUI代码

时间:2013-12-11 00:34:48

标签: c# user-interface blocking

我(希望)有一个直截了当的问题。我有一个在隐藏窗口中运行命令提示符命令的函数,并以字符串形式返回响应。此过程大约需要3秒钟。我想在GUI中添加一个简单的标签,该标签会在函数执行之前出现。标签只是说明正在检查某些内容,因此用户不认为界面只是缓慢或无响应。

以下是一个示例代码段。

        svnPathCheck_lbl.Visible = true; //Show the label     

        // Check validity of SVN Path
        string svnValidity = getCMDOutput("svn info " + SVNPath_txtbox.Text);

        // Here we call Regex.Match. If there is a 'Revision:' string, it was successful
        Match match = Regex.Match(svnValidity, @"Revision:\s+([0-9]+)", RegexOptions.IgnoreCase);

        svnPathCheck_lbl.Visible = false; //Hide the label

getCMDOutput()函数运行隐藏命令并阻止GUI。

我期望这样做是显示我的标签“正在检查...”,然后运行阻止功能getCMDOutput()。一旦函数返回并且GUI再次响应,它将隐藏标签。

相反,我从来没有看到标签显示出来。它几乎就像它从未执行过。是否可以在GUI有机会更新之前执行阻塞功能?

感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

试试这段代码,它应该有用......

    private void button1_Click(object sender, EventArgs e)
    {
        svnPathCheck_lbl.Text = "Checking...";
        svnPathCheck_lbl.Visible = true;

        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += bw_DoWork;
        bw.RunWorkerCompleted += bw_WorkCompleted;
        bw.RunWorkerAsync();
    }

    private void bw_WorkCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        svnPathCheck_lbl.Text = "Work completed";
    }

    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        string svnValidity = getCMDOutput("svn info " + SVNPath_txtbox.Text);
        Match match = Regex.Match(svnValidity, @"Revision:\s+([0-9]+)", RegexOptions.IgnoreCase);
    }

答案 1 :(得分:0)

我建议您异步运行getCMDOutput方法。

如果这是一个Windows窗体应用程序,您可以使用BackgroundWorker执行此操作。处理工作人员的DoWork事件以调用您的方法,以及您之前调用它的位置,改为backgroundWorker1.RunWorkerAsync()

这将导致该方法在新的thead中运行,因此UI更新将被单独处理并且将是即时的。

答案 2 :(得分:0)

试试这个:

svnPathCheck_lbl.Visible = true; //Show the label     
Task connectToSVN = new Task(() => { this.connectToSVN; }); connectToSVN.Start(); //Open new Task to complite the code without blocking the GUI.

private void connectToSVN 
{
    // Check validity of SVN Path
    string svnValidity = getCMDOutput("svn info " + SVNPath_txtbox.Text);

    // Here we call Regex.Match. If there is a 'Revision:' string, it was successful
    Match match = Regex.Match(svnValidity, @"Revision:\s+([0-9]+)", RegexOptions.IgnoreCase);
    this.Dispatcher.Invoke((Action)(() =>
    {
       svnPathCheck_lbl.Visible = false; //Hide the label
    }
    ));
}