Я использовал шаблоны T4 в sharp-архитектуре для генерации всего, от моделей до контроллеров и базовых представлений.
Определенно стоит проверить, даже если вы просто хотите увидеть несколько продвинутых примеров шаблонов T4 в действии.
Попробуйте вызвать вызов метода wait.setProgess ()
, поскольку wait
, похоже, находится в другом потоке, и это будет классический вызов перекрестного потока (о котором компилятор предупреждает вас, если вы ему позволите).
Поскольку Control.Invoke
немного неудобен в использовании, я обычно использую метод расширения, который позволяет мне передавать лямбда-выражение:
waiting.ThreadSafeInvoke(() => waiting.setProgress(...));
.
// also see http://stackoverflow.com/questions/788828/invoke-from-different-thread
public static class ControlExtension
{
public static void ThreadSafeInvoke(this Control control, MethodInvoker method)
{
if (control != null)
{
if (control.InvokeRequired)
{
control.Invoke(method);
}
else
{
method.Invoke();
}
}
}
}
Это звучит так, будто вы делаете все в потоке пользовательского интерфейса и, таким образом, не запускаете насос сообщений. Вы пробовали использовать сглаживание, подобное BackgroundWorker
и событие ProgressChanged
? См. Пример MSDN .
BackgroundWorker
идеально подходит для загрузки внешних данных, но учтите, что вы не должны выполнять никаких привязок данных и т. Д., Пока не вернетесь к потоку пользовательского интерфейса (или просто используйте Invoke
/ BeginInvoke
, чтобы передать работу потоку пользовательского интерфейса).
Первый. Я бы никогда не отключил параметр CheckForIllegalCrossThreadCalls.
Во-вторых. Добавьте Refresh () после обновления хода выполнения. Тот факт, что вы выполняете работу в другом потоке, не означает, что ваш поток графического интерфейса будет обновляться.
У меня такая же проблема. У меня есть форма с несколькими индикаторами выполнения (верхний, например, файл x / n, нижний - задача y / m) Верхний индикатор выполнения не обновляется ВОВРЕМЕННО , а нижний - Программно я обновляю его, делаю недействительным, явное сообщение процесса, обновление или сон не исправляет. Забавно то, что нижняя полоса прогресса и другой компонент (прошедшее время) обновляются нормально. Это чисто проблема темы Vista + (анимация, подобная предложенной ранее, XP или Vista с классической темой, работает нормально. When displaying a message box after the top progress bar has travelled to 100 (programmatically, not visually) I first see the message box and then I see the progress completing
I found that SetWindowTheme(ProgressBar.Handle, ' ', ' '); as explained on Disabling progress bar animation on Vista Aero works (but I have old style progress bars now)
Vista представила эффект анимации при обновлении индикатора выполнения - он пытается плавно прокручивать от предыдущей позиции к вновь установленной позиции, что создает неприятную задержку во времени при обновлении элемента управления. Отставание наиболее заметно, когда вы перепрыгиваете шкалу прогресса большими шагами, скажем, от 25% до 50% за один прыжок.
Как указал другой автор, вы можете отключить тему Vista для индикатора выполнения, и тогда он будет имитировать поведение индикаторов выполнения XP.
Я нашел другой обходной путь: если вы установите индикатор выполнения в обратном направлении, он будет немедленно покрасьте в это место. Итак, если вы хотите перейти с 25% до 50%, вы должны использовать (по общему признанию хакерскую) логику:
progressbar.Value = 50;
progressbar.Value = 49;
progressbar.Value = 50;
Я знаю, я знаю - это глупый прием, но он действительно работает!
Причина всей этой неразберихи - эффект интерполяции анимации, представленный Vista и W7. Это абсолютно не имеет ничего общего с проблемами блокировки потоков. Вызов setProgress () или прямая установка свойства Value запускает эффект анимации, который я объясню, как обмануть:
Я придумал хитрость для установки максимума в соответствии с фиксированным значением. Свойство maximum не запускает эффект, поэтому вы можете свободно перемещать прогресс с мгновенным ответом.
Помните, что фактический отображаемый прогресс задается: ProgressBar.Value / ProgressBar.Maximum. Имея это в виду, в приведенном ниже примере прогресс будет перемещен с 0 на 100, что подтверждается i:
ProgressBar works like this:
progress = value / maximum
therefore:
maximum = value / progress
Я добавил некоторые необходимые коэффициенты масштабирования, должно быть понятно:
progressBar1.Maximum *= 100;
progressBar1.Value = progressBar1.Maximum / 100;
for (int i = 1; i < 100; i++)
{
progressBar1.Maximum = (int)((double)progressBar1.Value / (double)(i + 1) * 100);
Thread.Sleep(20);
}