Обновить ярлык при обработке в 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..."
}
Каким будет пример кода?
Что именно это называется? Это потоки или делегаты?
Ответы
Ответ 1
Быстрое решение для вас:
Label1.Text = f.Name + " is done processing, now processing...";
Label1.Refresh();
Вы действительно хотите избежать DoEvents
, иначе у вас будут проблемы, если ваш пользователь несколько раз нажимает кнопки на вашей форме.
Ответ 2
Вы должны делать это в другом потоке, а затем обновлять свой поток пользовательского интерфейса из этого потока. Вы блокируете дальнейшую обработку, выполняя эту работу в потоке пользовательского интерфейса.
Если вы не можете переместить этот код в поток пользовательского интерфейса, вы всегда можете вызвать Application.DoEvents
, но я сильно предложите сначала изучить эти параметры:
Ответ 3
Вам нужно будет получить ваши данные из одного потока в другой. Это можно сделать несколькими способами...
Во-первых, ваш "фоновый" поток может обновить некоторую строковую переменную "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() из любого потока (пользовательского интерфейса или фона), и он обнаружит, нужно ли ему вызывать операцию в основном потоке пользовательского интерфейса (и если да, то делает это).
Чтобы настроить поток, вы можете сделать это следующим образом:
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().
Ответ 4
Если ваша обработка длительная, сделайте это в потоке рабочего стола.
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
Ответ 5
Threading.Sleep(milliseconds);
Хиты так быстро, что пользовательский интерфейс не может обновиться, поэтому вы можете просто поместить: testLabel.Refresh();
до вашего Threading.Sleep