2012-06-18 3 views
3

У меня есть библиотека с интерфейсом.Индикатор выполнения работает, но метка не обновляется

Public Interface Progress 
{ 
    int ProgressValue{get;set;}, 
    string ProgressText{get;set;}, 
} 

Библиотека имеет метод Create (фиктивный код):

Public Class TestLibrary 
{ 

    Progress _progress; 

    Public void Create() 
    { 
     foreach(var n in TestList) 
     { 
      // Do Something 
      _progress.ProgressValue = GetIndex(n); 
      _progress.ProgressText = "Updating..." + n; 
     } 
    } 
} 

У меня есть проект, который ссылается на эту библиотеку и вызовы Создать метод. Он даже реализует интерфейс.

Public Class TestProject : Progress 
{ 
    public int ProgressValue 
    { 
     get{return progressBar1.Value;} 
     set{progressBar1.Value = value;} 
    } 

    public int ProgressText 
    { 
     get{return label1.Text;} 
     set{label1.Text = value;} 
    } 
} 

Теперь, когда я запустить приложение, Бар Прогресс ведет себя правильно и показывает ход правильно, но текст label1 не меняется. Но он меняет конец цикла for и показывает последний элемент в цикле. Может ли кто-нибудь помочь мне в этом?

Примечание: все эти коды написаны непосредственно без тестирования, так как у меня нет приложения со мной. Извините за любые синтаксические ошибки.

+1

Меняет ли это, когда это * завершено * из интереса? Если это так, это, вероятно, проблема с потоками - похоже, что вы слишком много работаете в своем потоке пользовательского интерфейса. –

+0

@JonSkeet: Да, это действительно меняется. Я отредактировал вопрос, чтобы отразить то же самое. – Sandy

+0

это, безусловно, проблема с потоками - убедитесь, что ваш «прогресс» -Код не работает в потоке пользовательского интерфейса – Carsten

ответ

5

Использовался Label instead of ProgressBar. Вы можете попробовать этот код [using BackGroundWorker] -

using System.ComponentModel; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form3 : Form 
    { 
     private BackgroundWorker _worker; 
     BusinessClass _biz = new BusinessClass(); 
     public Form3() 
     { 
      InitializeComponent(); 
      InitWorker(); 
     } 

     private void InitWorker() 
     { 
      if (_worker != null) 
      { 
       _worker.Dispose(); 
      } 

      _worker = new BackgroundWorker 
      { 
       WorkerReportsProgress = true, 
       WorkerSupportsCancellation = true 
      }; 
      _worker.DoWork += DoWork; 
      _worker.RunWorkerCompleted += RunWorkerCompleted; 
      _worker.ProgressChanged += ProgressChanged; 
      _worker.RunWorkerAsync(); 
     } 


     void DoWork(object sender, DoWorkEventArgs e) 
     { 
      int highestPercentageReached = 0; 
      if (_worker.CancellationPending) 
      { 
       e.Cancel = true; 
      } 
      else 
      { 
       double i = 0.0d; 
       int junk = 0; 
       for (i = 0; i <= 199990000; i++) 
       { 
        int result = _biz.MyFunction(junk); 
        junk++; 

        // Report progress as a percentage of the total task. 
        var percentComplete = (int)(i/199990000 * 100); 
        if (percentComplete > highestPercentageReached) 
        { 
         highestPercentageReached = percentComplete; 
         // note I can pass the business class result also and display the same in the LABEL 
         _worker.ReportProgress(percentComplete, result); 
         _worker.CancelAsync(); 
        } 
       } 

      } 
     } 

     void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      if (e.Cancelled) 
      { 
       // Display some message to the user that task has been 
       // cancelled 
      } 
      else if (e.Error != null) 
      { 
       // Do something with the error 
      } 
     } 

     void ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      label1.Text = string.Format("Result {0}: Percent {1}",e.UserState, e.ProgressPercentage); 
     } 
    } 

    public class BusinessClass 
    { 
     public int MyFunction(int input) 
     { 
      return input+10; 
     } 
    } 
} 

Добавлено те же несколько дней назад here

+0

спасибо .... позвольте мне попробовать это, как только я доберусь до своего ноутбука – Sandy

+0

cool ... Его разумный/стандартный способ достичь таких задач в мире Winforms с помощью фонового рабочего. –

8

Похоже, что все ваши работы выполняются в потоке пользовательского интерфейса. Не делай этого.

Вместо этого запустите саму петлю в фоновом потоке, и использовать Control.Invoke или Control.BeginInvoke (вероятно, в Progress реализации) маршалу вызова через к потоку UI только для обновления пользовательского интерфейса. Это оставит ваш пользовательский интерфейс отзывчивым (и сможет обновлять ярлыки и т. Д.), Пока он все еще обрабатывается.

+0

спасибо .... позвольте мне попробовать это, как только я доберусь до своего ноутбука – Sandy

+0

Я принял этот ответ, и у меня не было большого понимания этих вещей ... После определенного количества опыта и знаний теперь я могу ясно видеть, что вы пытаетесь указать на то. Спасибо :) – Sandy

Смежные вопросы