2012-10-02 46 views
1

我正在使用后台工作人员更新sqlserver中的某些表。进度条最大值正在设置为正确的值,进度条值正在增加,背景工作器progresschanged正确调用正确的值,但酒吧没有进展。进度条未使用backgroundworker进度

这里是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(); 
} 
+1

是不是应该从'DoWork'内部调用'ReportProgress'或'updateProgressBarValue'? – Tudor

+0

我在DoWork方法和updateProgressBarValue方法之间没有看到任何连接。 – Tudor

+0

我是那个方法convert.OSGB36ToWGS84(“paf”)是在这个类内的不同的类,它调用updateprogressbarvalue –

回答

2

在报告你需要从后台工作触发一个事件来告诉它需要更新的进度进展。这可以使用以下方法完成:

backgroundWorker1.ReportProgress(10); 

将值更改为您需要证明代码中的进度增加。进度更改事件将主要在与GUI相同的线程上运行,因此您应该没有交叉线程问题。一个例外是,如果您的表单是通过加载项从Excel中调用的,则Excel将位于主线程中。

+0

updateProgressBarValue()从调用backgroundWorker1.ReportProgress(progressBar1.Value)的循环中调用; –

+0

我认为progressBar1.Value ++会尝试增加另一个线程中的值。尝试var progress = progressBar1.Value;然后在传递给ReportProgress时进度++ – InContext

-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; 
} 
+1

这是不正确的。 “ProgressChanged”的事件处理程序在UI线程上执行。 – Tudor

1

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

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

可以使用事件来做到这一点,但你最好使用代表或匿名函数。喜欢的东西...

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

然后就叫setProgress(0)通过setProgress(progressBar1.MaxValue)DoWork()方法

+0

updateprogressBarValue只会增加到由表中记录数设置的最大值,但不会超过此值。我认为内容是让后台工作人员完成大部分工作,留下UI来更新进度条 –

+0

对于您的体系结构,我仍然有点不清楚 - 从扩展的代码片段中,您的背景工作人员直接引用通过一个'con'变量到你的'InterfaceConvertLonLat' - 所以工人创建一个(表单?),然后有一个引用返回给工人?你似乎已经有参考文献在两个方向上运行?在任何情况下,你的工作者(线程A)调用'con.updateProgressBarValue()',然后在UI线程上增加'progressBar1.value()'控件 - 这将成为你的问题的根源。你能否提供关于执行流程的更多说明? – Basic

1

以下是严重的错误:

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

} 

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

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

如果一个异常逃脱你的DoWork,你永远不会知道发生了什么。

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(); 
}