从线程池c#更新进度条

时间:2011-10-05 05:33:53

标签: c# progress-bar threadpool

我尝试使用多线程处理一些数据,其中我使用线程池生成等于内核数量的线程(限于.NET 2.0到3.5,因此无法使用TPL)。

我的所有线程都在我的数据的不同部分执行相同的功能。

我的问题是我无法从线程池的线程更新进度条。找到了诸如invoke和Background worker之类的解决方案,但无法真正理解如何使用它们,请帮我解释如何使用它们。

我的代码看起来像

 private static float[] inpdat=new float[1000];//The input array to process
 //The spawned threads
 public void dowork(object o) 
 {
    int np = (int)o;
    for(int i=np;i<inpdat.length;i=i+Environment.ProcessorCount)
    {
         //do some processing
         if(np==0)
          {
              //update progress bar here
          }
    }
 }


    //The main thread
    for (int npou = 0; npou < numproc; npou++)
    {
        resetEvents[npou] = new ManualResetEvent(false);
        ThreadPool.QueueUserWorkItem(new WaitCallback(dowork), npou);
        PetrelLogger.InfoOutputWindow("manual reset event set");
    }

速度对我来说至关重要,如果跨线程调用占用最少的时间,那将非常有用。 谢谢

3 个答案:

答案 0 :(得分:1)

以下是一个例子:

ThreadPool.QueueUserWorkItem(new WaitCallback(o =>
    {
        // worker method implementation
        .....
        progressBar1.Invoke(new MethodInvoker(() => progressBar1.Value = 20));
    }));

答案 1 :(得分:0)

您可以使用进度条更新用户控件。 添加表单作为输入参数,或为结果添加一些回调接口,表单将实现:

interface IMyCallback
{
    void Progress(int progress);
}

在表单实现中添加以下代码:

void Progress(int Progress)
{
    if(this.InvokeRequired)
    {
        this.BeginInvoke(new ParametrizedThreadStart(Inv_Progress), Progress);
    }
    else
    {
        Inv_Progress(Progress);
    }
}

void Inv_Progress(object obj)
{
    int progress = obj as int;
    // do your update progress bar work here

}

现在您可以执行以下操作:

public void dowork(object o) 
 {
    int np = (int)o;
    for(int i=np;i<inpdat.length;i=i+Environment.ProcessorCount)
    {
         //do some processing
         if(np==0)
          {
              myCallback.Progress(0);
          }
    }
 }

答案 2 :(得分:0)

标准调用可能最简单,您可以使用匿名委托使其更清晰。

int n = 5;
myProgressBar.Invoke(
    delegate
    {
        myProgressBar.Value = n;
    }
);

请记住,在某些情况下(例如,在一个线程内循环使用此委托),您可能需要声明委托并将值作为参数传递给它。如果不这样做,您可能会对当地人产生奇怪的行为。这也是使用匿名方法和Action类的情况。