undip_student
undip_student

Reputation: 157

Progress Bar in WPF - stuck in 50%

So I have a class with a BackgroundWorker and a ProgressBar on its GUI like this

public class mCrypt
{
   public byte[] DataBlock;
   public byte[] IVBlock;
   public static Bitmap FingerprintImg;
   public byte[] TempX;
   public byte[] TempAngles;
   public byte[] TempY;
   public byte[] TempKey;
   public byte[] X;
   public byte[] Y;
   public byte[] Angles;
   public byte[] Key;
   public int NoM;

   public mCrypt(BackgroundWorker bw, string imgLoc, string fileLoc, byte[] ivBlock)
   {
      if (!bw.CancellationPending)
      {
         bw.ReportProgress(0);
         LoadImg(imgLoc);
         bw.ReportProgress(7);
         DetectMinutiae(FingerprintImg);
         bw.ReportProgress(25);
         ConvertValues();
         bw.ReportProgress(30);
         LoadFile(fileLoc);
         // This LoadFile method contains DataBlock = File.ReadAllBytes(fileloc);
         bw.ReportProgress(35);
         HandleLength(ivBlock);
         bw.ReportProgress(40);
         ManageInitKey();
         bw.ReportProgress(45);
         GenerateKey();
         bw.ReportProgress(50);
      }
   }

   public byte[] EncryptFile(BackgroundWorker bgw)
   {
      if(!bw.CancellationPending)
      {
         for(int i = 0, i < (DataBlock.Length / 16), i++)
         {
            //Doing cryptographical process here
            ...
            //ProgressBar updates
            if((i / (DataBlock.Length / 16)) + 50 != 100)
               bgw.ReportProgress((i / (DataBlock.Length / 16)) + 50);
            else
               bgw.ReportProgress(100);
         }
      }
   }
}

As I tried to run the app, the ProgressBar only updates when constructor runs. Leaving the ProgressBar in 50% state until the process finish. I don't understand why it didn't work. Any idea? Thanks in advance

Upvotes: 2

Views: 359

Answers (2)

ANewGuyInTown
ANewGuyInTown

Reputation: 6437

Do not touch the UI thread from the background worker process directly. Use Invoke or BeginInvoke to modify the UI

Inside worker process thread:

    bw.DoWork += (sender, args) =>
    {
    Dispatcher.BeginInvoke(DispatcherPriority.Loaded,new Action(()=>
                            {
                                //code that changes progress-bar
                            }
                           ));
     }

Upvotes: 0

Grant Winney
Grant Winney

Reputation: 66439

You're not using your BackgroundWorker correctly, and you're locking the UI thread.

Move the calls to LoadImg(), LoadFile(); and ReportProgress() into the DoWork event. Also, you may have to modify what those methods are doing, if they touch the UI at all.

I'd also recommend reading this: Threading in C#: BackgroundWorker

Upvotes: 2

Related Questions