【问题标题】:Progress bar not working on button click C# windows application进度条在按钮上不起作用单击 C# windows 应用程序
【发布时间】:2015-03-13 21:12:04
【问题描述】:

我想同步我的本地和网络数据库,所以我使用链接服务器编写了一个存储过程。我的存储过程执行良好,数据同步成功,但执行过程大约需要 7-10 分钟。确切的时间无法确定。因此,每当该过程在我的 Windows 应用程序上运行时,页面似乎就好像它已经变得无响应,尽管该过程仍在继续。 所以我在我的页面上有一个“数据同步”按钮,点击它我希望进度条显示存储过程的进度。目前,我取最后几个执行时间的平均值来定义存储过程运行的持续时间。现在的问题是,当我单击数据同步按钮时,进度条不起作用。请帮我解决这个问题。

我的代码如下:-

namespace RMS
{
    public partial class DataSync : Form
    {
        connection con = new connection();
        SqlCommand cmd = new SqlCommand();

    static int rowCount;
    static int syncTime;
    static int timeSlice;

    public DataSync()
    {
        InitializeComponent();
    }

    private void btnDataSync_Click(object sender, EventArgs e)
    {
            // Start the asynchronous operation.
           backgroundWorker1.RunWorkerAsync();

        try
        {

            con.GetConnectLive();
            con.GetConnect();

            if (con.CnLive.State == ConnectionState.Open)
            {
                MessageBox.Show("Connection to Live Server Successful!!!...Data Synchronisation may take several minutes so do not cancel the operation while in execution mode");

                btnDataSync.Enabled = false;
               btnDataSync.Text = "Please Wait...";

                string Str = "RMS_LocalToLive";
                cmd = new SqlCommand(Str, con.Cn);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandTimeout = 1200;

                rowCount = cmd.ExecuteNonQuery();


                if (rowCount > -1)
                {
                    MessageBox.Show("Total no. of rows synchronised = " + rowCount);
                    btnDataSync.Text = "Success";
                }
                else
                {
                   MessageBox.Show("Data Synchronisation couldn't be completed because of connection problem... Please try again!!!");
                }

            }
            else
            {
               MessageBox.Show("Unable to connect to Live Server...Please check your internet connection and try again!!!");
            }


            con.GetDisConnect();
            con.GetDisConnectLive();
        }
        catch (Exception ex)
        {
           MessageBox.Show("Please check your internet connection and try again!!!");
        }

    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            con.GetConnect();

            string Str = "RMS_DataSyncTime";
            cmd = new SqlCommand(Str, con.Cn);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandTimeout = 1200;

            syncTime = Convert.ToInt32(cmd.ExecuteScalar().ToString());

            timeSlice = syncTime / 100;

            con.GetDisConnect();


        }
        catch (Exception ex)
        {
            MessageBox.Show("Unable to retrieve last Data Synchronisation Timing");
        }

        for (int i = 1; i <= synctime; i=i+timeslice)
        {

        Thread.Sleep(timeslice);  
        // Report progress.
         backgroundWorker1.ReportProgress(i);
        }


    }

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // Change the value of the ProgressBar to the BackgroundWorker progress.
        progressBar1.Value = e.ProgressPercentage;
        // Set the text.
        this.Text = e.ProgressPercentage.ToString() + "% Completed";
    }

    private void DataSync_Load(object sender, EventArgs e)
    {

    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgse)
    {

    }
}

}

【问题讨论】:

  • 我不明白你在这里做什么。当您第一次运行您的后台工作人员应该执行的代码,然后执行一个 for 语句时,您在每次迭代中报告进度,进度不会显示任务的实际进度,它会执行任务,然后模拟一个进度实际上只是代码中应该报告进度的部分中的虚构进度,这真的是您想要实现的目标,还是您想要在开始进度报告之前推进已经完成的实际任务的进度?
  • 我想在后台执行存储过程时同时显示进度条的进度...当存储过程完全执行时进度条应该显示100%...请纠正我的代码并粘贴新代码...

标签: c# progress-bar backgroundworker


【解决方案1】:

这里的主要问题是,当您在BackgroundWorker 的线程中执行进度条更新时,ReportProgress() 更新永远不会进入 UI 线程,因为您已经用主线程阻止了该线程SQL 操作。

您应该这样做,而不是这样做:

private void btnDataSync_Click(object sender, EventArgs e)
{
    // Start the asynchronous operation.
    backgroundWorker1.RunWorkerAsync();

    btnDataSync.Enabled = false;
    btnDataSync.Text = "Please Wait...";

    bool success = false;

    try
    {
        // Execute the query asynchronously
        success = await Task.Run(() => ExecuteLocalToLive());
    }
    catch (Exception ex)
    {
       MessageBox.Show("Please check your internet connection and try again!!!");
    }

    btnDataSync.Enabled = true;
    btnDataSync.Text = success ? "Success" : "Failure";
}

private bool ExecuteLocalToLive()
{
    bool success = false;

    con.GetConnectLive();
    con.GetConnect();

    if (con.CnLive.State == ConnectionState.Open)
    {
        MessageBox.Show("Connection to Live Server Successful!!!...Data Synchronisation may take several minutes so do not cancel the operation while in execution mode");

        string Str = "RMS_LocalToLive";
        cmd = new SqlCommand(Str, con.Cn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandTimeout = 1200;

        rowCount = cmd.ExecuteNonQuery();

        if (rowCount > -1)
        {
            MessageBox.Show("Total no. of rows synchronised = " + rowCount);
            success = true;
        }
        else
        {
           MessageBox.Show("Data Synchronisation couldn't be completed because of connection problem... Please try again!!!");
        }
    }
    else
    {
       MessageBox.Show("Unable to connect to Live Server...Please check your internet connection and try again!!!");
    }

    con.GetDisConnect();
    con.GetDisConnectLive();

    return success;
}

我重新安排了处理按钮状态和文本的代码,以便它仍然在它所属的 UI 线程中执行,即使方法本身不是。您似乎也从未将按钮设置回启用状态;我不清楚这是否是故意的,所以我继续并添加了一行来做到这一点。

最后,我强烈建议您找出一种向用户报告状态的更好方法,而不是您现在对MessageBox.Show() 的调用。最大的问题是,在用户关闭初始消息之前,您甚至不会开始做任何工作,这会立即使您的进度条与实际工作不同步。但最好将所有 UI 保留在 UI 线程中,并将 UI 与非 UI 逻辑(即 SQL 操作)分开。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-17
    相关资源
    最近更新 更多