2014-09-11 67 views
2

我想使用進度條創建基本的多線程應用程序。這意味着這個進度條會在不同的線程上運行,而主線程正忙於它正在執行的大進程。我見過很多關於它的教程。但是他們是多線程的東西就是做這個大進程的東西。另一種形式的進度條只是顯示一個簡單的進度條,它使用計時器運行並完成。如何使進度條在C#中的不同線程中運行

這是我現在的代碼。

對於螺紋:

public void thread() 
{ 
    Form6 for6 = new Form6(); 
    for6.Show(); 
} 


TH1 = new Thread(thread); 
TH1.Start(); 

進度條(代碼內部形狀6)

private void timer1_Tick(object sender, EventArgs e) 
    { 
     progressBar1.Increment(+1); 
     if (progressBar1.Value == 99) 
     { 
      this.Close(); 
     } 
    } 

    private void Form6_Load(object sender, EventArgs e) 
    { 
     timer1.Start(); 
    } 

我的問題是在這裏線程不運行Form6。有什麼辦法可以做到這一點?

+0

表單只能在單線程單元(STA)中工作。 – gabba 2014-09-11 04:41:22

+0

@gabba所以這是不可能的?? – 2014-09-11 04:47:26

+0

最新情況?第二種形式是否出現? – Sayka 2014-09-11 04:53:48

回答

3

代替ProgressBar,你應該將你的長期運行的非UI代碼移動到一個單獨的線程中。在WinForms中執行此操作的標準和更簡單的方法是使用BackgroundWorker組件,該組件可以提升ProgressChanged事件,您可以在其中更新UI。重要的是要注意ProgressChanged事件是在UI線程上產生的,而不是在工作線程上產生的,因此您甚至不需要使用Invoke()來執行UI操作(例如更新ProgressBar)。

2

必須使用Control.Invoke爲避免交叉線程的問題,但我更喜歡使用BackgroundWorker爲解決這個問題,創建一個_fieldForm6和使用進度在ProgressChanged事件有關詳細信息,請參閱本page

public void thread() 
     { 
      Form6 for6=null; 
      Application.OpenForms[0].Control.Invoke(delegate{ 
      for6 = new Form6(); 
      for6.Show(); 
     }); 
    } 
+0

謝謝,但您在頂部提供的代碼似乎有問題。我得到的錯誤是「不能轉換匿名方法鍵入'System.Delegate',因爲它不是委託類型」 – 2014-09-11 06:13:00

+1

@LucasJuan。使用類型轉換來轉換匿名方法的'Action',Control.Invoke((Action)delegate {' – MajidTaheri 2014-09-11 08:14:15

+0

還有一些sir錯誤非靜態字段,方法或屬性'System.Windows需要對象引用。 Forms.Control.Invoke(System.Delegate)' – 2014-09-11 09:27:08

1

您可以使用Background工具進行所有處理,而不是使用主線程進行大型處理。

下面是一個簡單的例子。

public partial class Form1 : Form 
    { 
     BackgroundWorker bgw = new BackgroundWorker();  
     public Form1() 
     { 
      InitializeComponent(); 
      label1.Text = ""; 
      label2.Text = ""; 
     } 

     private void button1_Click_1(object sender, EventArgs e) 
     { 
      bgw.DoWork += new DoWorkEventHandler(bgw_DoWork); 
      bgw.ProgressChanged += new ProgressChangedEventHandler(bgw_ProgressChanged); 
      bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted); 
      bgw.WorkerReportsProgress = true; 
      bgw.RunWorkerAsync(); 
     } 

     void bgw_DoWork(object sender, DoWorkEventArgs e) 
     { 
      int total = 57; //some number (this is your variable to change)!! 

      for (int i = 0; i <= total; i++) //some number (total) 
      { 
       System.Threading.Thread.Sleep(100); 
       int percents = (i * 100)/total; 
       bgw.ReportProgress(percents, i); 
       //2 arguments: 
       //1. procenteges (from 0 t0 100) - i do a calcumation 
       //2. some current value! 
      } 
     } 

     void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      progressBar1.Value = e.ProgressPercentage; 
      label1.Text = String.Format("Progress: {0} %", e.ProgressPercentage); 
      label2.Text = String.Format("Total items transfered: {0}", e.UserState); 
     } 

     void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      //do the code when bgv completes its work 
     } 
    } 
相關問題