2009-02-20 12 views
26

Каков наилучший способ обновления ярлыка приложения Windows Forms во время обработки?Обновление метки во время обработки в Windows Forms

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

foreach (System.IO.FileInfo f in dir.GetFiles("*.txt")) 
{ 
    // Do processing 
    // Show progress bar 
    // Update Label on Form, "f.Name is done processing, now processing..." 
} 

Какой будет образец кода?

Что именно называется? Это потоки или делегаты?

ответ

48

Быстрое исправление для вас будет:

Label1.Text = f.Name + " is done processing, now processing..."; 
Label1.Refresh(); 

Вы действительно хотите, чтобы избежать DoEvents, в противном случае вы будете иметь проблемы, если ваш пользователь несколько раз нажимает кнопки на форме.

13

Вы должны делать это в другом потоке, а затем обновляет свой UI нить из этого потока. Вы блокируете дальнейшую обработку, выполняя эту работу в потоке пользовательского интерфейса.

Если вы не перенести этот код в поток пользовательского интерфейса, то вы всегда можете позвонить Application.DoEvents, но я сильно предлагает вам изучить эти варианты первым:

+1

Я согласен с этим - особенно для BackgroundWorker. Я часто использую его сам.BackgroundWorkers делают многопоточные операции, такие как простые и простые! – Keithius

13

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

Во-первых, ваша «фоновая» нить может обновлять строчную переменную «CurrentStatus», которая изменяется вместе с ней. Затем вы можете поместить таймер в свою форму, чтобы затем захватить переменную CurrentStatus и обновить ее.

Во-вторых, вы можете просто вызвать операцию из фонового потока в поток пользовательского интерфейса с помощью делегата, используя свойство InvokeRequired элемента управления меткой. Так, например ...

private delegate void UpdateStatusDelegate(string status); 
private void UpdateStatus(string status) 
{ 
    if (this.label1.InvokeRequired) 
    { 
     this.Invoke(new UpdateStatusDelegate(this.UpdateStatus), new object[] { status }); 
     return; 
    } 

    this.label1.Text = status; 
} 

Вы можете назвать это UpdateStatus() метод из любого потока (UI или фона), и он будет определять, нужно ли оно или нет, чтобы вызвать операцию на основном потоке пользовательского интерфейса (и если да, то).

Чтобы реально создать нить, вы можете сделать это так:

private void StartProcessing() 
    { 
     System.Threading.Thread procThread = new System.Threading.Thread(this.Process); 

     procThread.Start(); 
    } 

    private void Process() // This is the actual method of the thread 
    { 
     foreach (System.IO.FileInfo f in dir.GetFiles("*.txt")) 
     { 
      // Do processing 
      // Show progress bar 
      // Update Label on Form, "f.Name is done processing, now processing..." 
      UpdateStatus("Processing " + f.Name + "...");     
     } 
    } 

Затем, когда пользователь нажимает на кнопку «GO», вы будете просто вызвать StartProcessing().

+1

Это должен быть идеальный ответ. –