2015-05-13 55 views
-1

刪除我請 我決定用一個新的下載功能重新編寫所有在標籤C#BackgroundWorker的下載進度,得到字節標籤

+0

可能重複(http://stackoverflow.com/questions/15759688/update-label-text-in-background-worker-winforms) – demonplus

+0

歡迎在本網站約翰。如果你想更好的機會得到答案,看看這個:http://stackoverflow.com/help/how-to-ask –

+0

@demonplus那個人在該帖子是使用backgroundworker插入MySQL值。 我不是。你應該閱讀帖子,然後說它是重複的 –

回答

2

以下是使用BackgroundWorker更新Form1上的標籤的一些工作代碼。

創建一個新的Windows窗體項目並將其放入您的代碼,它會工作。 這是超級醜陋的,但它的作品。 之後,只需將代碼插入DoWork方法並計算您的值併發送到ReportProgress。

請記住,在DoWork方法中完成的工作是實際的後臺線程。 這意味着在該方法(DoWork)中,您無法訪問UI(表單)元素,因爲它們在UI線程上。

enter image description here

public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
      backgroundWorker1.DoWork += backgroundWorker1_DoWork; 
      backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged; 
      backgroundWorker1.WorkerReportsProgress = true; 
      backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted; 
     } 

     void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      button1.Enabled = true; 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      button1.Enabled = false; 
      backgroundWorker1.RunWorkerAsync(); 
     } 

     void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      label1.Text = e.ProgressPercentage.ToString(); 
     } 

     void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      FakeCountingWork(); 
     } 


     private void FakeCountingWork() 
     { 
      int totalNumber = 100; 
      int progressCounter = 0; 
      while (progressCounter < totalNumber) 
      { 
       int fakecounter = 0; 
       for (int x = 0; x < 100000000; x++) 
       { 
        fakecounter++; 
       } 
       progressCounter++; 
       backgroundWorker1.ReportProgress(progressCounter); 
      } 
     } 
    } 
##################################編輯追加其他功能

好的,下面介紹如何實現顯示迄今爲止下載的字節數的標籤。 將第二個名爲label2的標籤添加到您的表單中。
接下來,改變我之前示例中的以下方法。 這裏我們將使用UserState向ProgressChanged事件傳遞一個額外的值。這很簡單。您可以看到我正在生成一個隨機數,現在它將出現在Label2中。這是你可以顯示你的字節數的地方。

void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      label1.Text = e.ProgressPercentage.ToString(); 
      label2.Text = e.UserState.ToString(); 
     } 

private void FakeCountingWork() 
     { 
      int totalNumber = 100; 
      int progressCounter = 0; 
      Random rnd = new Random(); 
      while (progressCounter < totalNumber) 
      { 
       int fakecounter = 0; 
       for (int x = 0; x < 100000000; x++) 
       { 
        fakecounter++; 
       } 
       progressCounter++; 
       updateValue = rnd.Next(); 
       backgroundWorker1.ReportProgress(progressCounter,updateValue); 
      } 
     } 

enter image description here

[在後臺工作的WinForms更新標籤文本]的
+1

這就像一個魅力(顯示百分比部分)謝謝你! –

+0

@JohnK我添加了實現UserState對象的附加功能,並將一個附加值傳遞給ProgressChanged事件,以向您展示如何使用另一個標籤顯示字節數。 – raddevus

+0

我不確定如何使用我的int64 iSize值進行這項工作,但是,我一定會嘗試使用它,謝謝! –

0

我猜想這是因爲你正試圖在不同的線程更新UI對象。如果使用wpf,你是否嘗試過使用Dispatcher? https://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.invoke(v=vs.110).aspx

或者使用Winforms進行調用? https://msdn.microsoft.com/fr-ca/library/zyzhdc6b(v=vs.85).aspx

編輯: 作爲@daylight指出的是,該UI是在progresschanged事件,執行其創建的後臺工作的線程上被更新,因此不應該有關於線程的問題。請參閱https://msdn.microsoft.com/en-us/library/ka89zff4(v=vs.110).aspx以獲取更多信息

+0

我認爲@demonplus發佈的鏈接會很有幫助。無論後臺工作人員在做什麼,它與UI對象所在的線程都是不同的線程,因此您不能像往常一樣更新它們。 – User92

+0

實際上,他似乎只是在ProgressChanged事件中更新UI線程對象(標籤)。使用ProgressChanged事件更新UI元素是正確的方法,您可以看到它在我更新表單上的標籤的答案中起作用。你不能從DoWork()方法訪問UI(表單)元素---這是一個單獨的執行線程,並且會失敗。 – raddevus

+1

@daylight非常真實,我沒有想到這一點。對於任何需要確認的人,文章https://msdn.microsoft.com/en-us/library/ka89zff4(v=vs.110).aspx指出:「ProgressChanged事件處理程序在創建BackgroundWorker的「。我是StackOverflow的新手,你是否建議我刪除我的答案或離開? – User92