2014-02-17 2 views
1

Я пытаюсь вычислить хэш-файл md5 и поместить его в текстовое поле, у меня также есть ProgressBar, который должен продолжать работать, пока хеш, если он вычисляется, я устанавливаю ProgressBar в Marquee, а панель будет работать, пока я выберу файл, но как только начнется вычисление хеша, бар замерзает, пока он не будет выполнен. Вот мой код:C# ProgressBar Freezing

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Diagnostics; 
using System.Drawing; 
using System.IO; 
using System.Linq; 
using System.Security.Cryptography; 
using System.Text; 
using System.Text.RegularExpressions; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Windows.Forms; 


namespace Calcula_MD5_BAR 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      Stopwatch timer = new Stopwatch(); 
      var openFileDialog1 = new OpenFileDialog(); 
      progressBar1.Style = ProgressBarStyle.Marquee; 
      progressBar1.MarqueeAnimationSpeed = 30; 
      if (openFileDialog1.ShowDialog() == DialogResult.OK) 
      {  
       timer.Start(); 
       textBox1.Text = GetFileMD5Hash(openFileDialog1.FileName); 
       timer.Stop(); 
       lblTime.Text = timer.Elapsed.ToString(); 
       progressBar1.Style = ProgressBarStyle.Continuous; 
       progressBar1.Increment(100); 
      } 
      progressBar1.MarqueeAnimationSpeed = 0; 
     } 

     protected string GetFileMD5Hash(string nomeArquivo) 
     { 
      FileStream file = new FileStream(nomeArquivo, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 
      MD5 md5 = new MD5CryptoServiceProvider(); 
      byte[] retVal = md5.ComputeHash(file); 
      file.Close(); 

      StringBuilder sb = new StringBuilder(); 
      for (int i = 0; i < retVal.Length; i++) 
      { 
       sb.Append(retVal[i].ToString("x2")); 
      } 
      return sb.ToString(); 
     } 



    } 
} 
+0

Это совершенно нормально. Индикатор выполнения не может перерисовываться, ваша ветка пользовательского интерфейса отключена в лесу, что-то делает, и не заботится о потребностях в пользовательских интерфейсах. Пользовательский интерфейс полностью заморожен, он не реагирует на ввод и не перерисовывает себя. Используйте BackgroundWorker для запуска метода GetFileMD5Hash(). –

+0

Ваша функция 'GetFileMD5Hash (openFileDialog1.FileName)' блокирует ее. вы должны запустить его в другом потоке – bansi

+0

Вам нужно переместить интенсивную работу в отдельный поток, таким образом, поток пользовательского интерфейса может свободно управлять пользовательским интерфейсом. Изучите [BackgroundWorker] (http://msdn.microsoft.com/en-us/library/cc221403 (v = vs.95) .aspx) – musefan

ответ

3

Вы должны делать свою работу без пользовательского интерфейса в потоке без пользовательского интерфейса. await помогает при создании асинхронности разгружая работу на другой поток и сортировочной результат обратно в поток пользовательского интерфейса много легче работать:

private async void button1_Click(object sender, EventArgs e) 
{ 
    Stopwatch timer = new Stopwatch(); 
    var openFileDialog1 = new OpenFileDialog(); 
    progressBar1.Style = ProgressBarStyle.Marquee; 
    progressBar1.MarqueeAnimationSpeed = 30; 
    if (openFileDialog1.ShowDialog() == DialogResult.OK) 
    {  
     timer.Start(); 
     textBox1.Text = await Task.Run(() => 
      GetFileMD5Hash(openFileDialog1.FileName)); 
     timer.Stop(); 
     lblTime.Text = timer.Elapsed.ToString(); 
     progressBar1.Style = ProgressBarStyle.Continuous; 
     progressBar1.Increment(100); 
    } 
    progressBar1.MarqueeAnimationSpeed = 0; 
} 
1

Использование фона рабочий! Полный пример можно найти здесь (вставили ниже!):

http://www.codeproject.com/Tips/83317/BackgroundWorker-and-ProgressBar-demo

Просто установите стиль шатер

public partial class Form1 : Form 
    { 
      public Form1() 
      { 
        InitializeComponent(); 
        Shown += new EventHandler(Form1_Shown); 

        // To report progress from the background worker we need to set this property 
        backgroundWorker1.WorkerReportsProgress = true; 
        // This event will be raised on the worker thread when the worker starts 
        backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork); 
        // This event will be raised when we call ReportProgress 
        backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged); 
      } 
      void Form1_Shown(object sender, EventArgs e) 
      { 
        // Start the background worker 
        backgroundWorker1.RunWorkerAsync(); 
      } 
      // On worker thread so do our thing! 
      void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
      { 
        // Your background task goes here 
        for (int i = 0; i <= 100; i++) 
        { 
          // Report progress to 'UI' thread 
          backgroundWorker1.ReportProgress(i); 
          // Simulate long task 
          System.Threading.Thread.Sleep(100); 
        } 
      } 
      // Back on the 'UI' thread so we can update the progress bar 
      void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
      { 
        // The progress percentage is a property of e 
        progressBar1.Value = e.ProgressPercentage; 
      } 
    }