1

我正在使用后台工作人员更新 sqlserver 中的一些表。进度条最大值被设置为正确的值,进度条的值正在递增,backgroundworker progresschanged 正在以正确的值正确调用,但进度条没有进展。

这是 background_dowork 方法中表单的代码,有一个循环调用 updateProgressBarValue,它使用正确的值。

public InterfaceConvertLonLat()
{
    InitializeComponent();
    Shown += new EventHandler(Form1_Shown);
    backgroundWorker1.WorkerReportsProgress = true;
    backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
    backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
}

public void ConvertLonLat_Load(object sender, EventArgs e)
{ 
}

public void updateProgressBarValue()
{
    progressBar1.Value++;
    backgroundWorker1.ReportProgress(progressBar1.Value);
}

public void setProgressBarMax(int max)
{
    progressBar1.Maximum = max;
    MessageBox.Show("setprogressbarmax " + max);
}

public void Form1_Shown(object sender, EventArgs e)
{     
    backgroundWorker1.RunWorkerAsync();
}

public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    convert.OSGB36ToWGS84("paf");
}

public void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

这是另一个调用 updateprogressbarvalue 的类中包含的循环,它正在被触发,并且如前所述 backgroundworker1_progressChanged 正在被触发,但条没有移动。

con.setProgressBarMax(address.Tables[0].Rows.Count); 

foreach (DataRow LonLat in address.Tables[0].Rows)
{
    con.updateProgressBarValue();
    Double lon = 0;
    Double lat = 0;
    lat = Convert.ToDouble(LonLat["LTO"]);
    lon = Convert.ToDouble(LonLat["LGO"]);
    LocalToWGS84(ref lat, ref lon, OGB_M);

    cmd1.Parameters["@LTW"].Value = lat;
    cmd1.Parameters["@LGW"].Value = lon;

    string dbQuery1 = "update " + tableName + " set LTW = @LTW, LGW = @LGW";

    cmd1.CommandText = (dbQuery1);
    cmd1.CommandType = CommandType.Text;
    cmd1.Connection = conn;
    cmd1.ExecuteNonQuery();
}
}
catch (Exception e)
{
    MessageBox.Show("error converting: " + e.Message);
}
finally
{
    conn.Close();
}
4

5 回答 5

2

报告进度时,您需要从后台工作人员触发一个事件来告诉进度条它需要更新。这可以使用以下方法完成:

backgroundWorker1.ReportProgress(10);

将值更改为您需要的值,以证明您的代码取得了更大的进步。进度更改事件将主要在与您的 GUI 相同的线程上运行,因此您应该没有跨线程问题。一个例外是,如果您的表单是通过插件从 Excel 调用的,在这种情况下 Excel 将位于主线程上。

于 2012-10-02T10:00:29.400 回答
1

你有很多问题——你UpdateprogressBarValue()只是增加了进度条的值,但没有跟踪它被调用的次数/当前值是多少——所以如果你调用它 101 次(假设范围为0-100),你会得到一个OutOfRangeException

您的DoWork()方法似乎根本没有调用更新(直接或通过引发事件)。

可以使用事件来执行此操作,但最好使用委托或匿名函数。就像是...

public void setProgress(int value) {
    progressBar1.invoke(delegate{ progressBar1.Value = value; }
}

然后只需setProgress(0)setProgress(progressBar1.MaxValue)您的DoWork()方法中调用

于 2012-10-02T10:19:17.487 回答
1

以下是严重错误的:

public void updateProgressBarValue()
{
    progressBar1.Value++;   // not thread-safe
    backgroundWorker1.ReportProgress(progressBar1.Value);

}

ReportProgress()旨在被称为表单 DoWork,它甚至不应该读取 Control 属性。
您应该在 foreach 循环中维护一个计数器并将其提供给进度机制。

现在这并不能直接表明它为什么不移动,但您没有 Completed 处理程序。你确定这个过程已经完成了吗?

如果您的 DoWork 出现异常,您将永远不知道发生了什么。

于 2012-10-02T11:48:45.203 回答
0
private void Form1_Load(object sender, System.EventArgs e)
{
    // Start the BackgroundWorker.
    backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 1; i <= 100; i++)
    {
    // Wait 100 milliseconds.
    Thread.Sleep(100);
    // Report progress.
    backgroundWorker1.ReportProgress(i);
    }
}

private void backgroundWorker1_ProgressChanged(object sender, progress e)
{
    // Change the value of the ProgressBar to the BackgroundWorker progress.
    progressBar1.Value = e.ProgressPercentage;
    // Set the text.
    this.Text = e.ProgressPercentage.ToString();
}
于 2013-02-28T09:00:22.083 回答
-2

我认为这可能是由于 Windows 窗体中的 UI 在其自己的线程/上下文中运行的事实引起的。在这种情况下,您可能需要使用Invoke来对 UI 进行调整。

像这样的东西:

public void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    Invoke(new ProgressDelegate(UpdateProgress), e.ProgressPercentage);
}

delegate void ProgressDelegate(decimal value);

private void UpdateProgress(decimal value)
{
    progressBar1.Value = value;
}
于 2012-10-02T09:29:18.330 回答