2012-10-02 464 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(); 
}