2014-09-11 77 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 
     } 
    } 
相关问题