VB.Net: понимание того, как работает Application.Run () - PullRequest
2 голосов
/ 04 ноября 2010

Ханс Пассант дал мне отличный ответ здесь , поэтому я подумал попросить более подробную информацию, чтобы попытаться понять, как Application.Run() работает.

Насколько я понимаю изdocs, кажется, что Application.Run() запускает цикл сообщений в текущем потоке, который, в свою очередь, позволяет ему обрабатывать пользовательский ввод (это верно?).Перегруженная версия Application.Run(Form) в основном делает то же самое, только она существует, когда форма закрывается, и показывает форму по умолчанию.

Это поднимает несколько вопросов:

Как бынужно просто вызвать из подпрограммы Main() функцию, которая может взаимодействовать с пользователем (окна сообщений и т. д.), и дождаться ее выхода?

Когда цикл обработки сообщенийзапускается без формы, как вы запускаете новую форму из этого цикла и ждете ее выхода?ShowDialog может работать, если только вы не хотите, чтобы форма отображалась сразу после запуска (например, если у вас есть запущенный файл, свернутый в системный трей)
  • По сути,Ситуация будет выглядеть следующим образом: sub `Main` имеет список задач, которые нужно выполнить за 20 минут, с иконкой в ​​системном трее, сообщающей пользователю, что программа будет работать через 20 минут.Таймер срабатывает через 20 минут и должен выполнить, скажем, ок.15 задач одна за другой, каждый раз создавая экземпляр диалогового окна прогресса, изначально скрытого на панели задач.
  • `ShowDialog` будет отображать ненужную форму;таким образом, я бы передал диалогу выполнения функцию обратного вызова функции, которая запускает следующую задачу.Но это не могло бы выйти из первой формы прогресса до того, как вышла вторая, не так ли?Что означает, что 15 форм в конечном итоге будут открыты ...
  • Таким образом, решение может состоять в том, чтобы вызвать (begininvoke?) Обратный вызов в главном цикле приложения ... Только я не знаю, как это сделать, потому что у меня нет формы, связанной с циклом для вызова обратного вызова ...

Надеюсь, мои вопросы ясны (я могу многое перепутать, извините),
Спасибо,
CFP.

1 Ответ

3 голосов
/ 04 ноября 2010

Перетащите Timer, ProgressBar и BackgroundWorker на форму. Первое, что вы хотите сделать, - это предотвратить отображение формы при запуске программы. Вставьте этот код в класс формы:

Protected Overrides Sub SetVisibleCore(ByVal value As Boolean)
    If Not Me.IsHandleCreated Then
        value = False
        Me.CreateHandle
    End If
    MyBase.SetVisibleCore(value)
End Sub

Используйте таймер, чтобы начать работу. Установите его свойства Interval и Enabled, добавьте обработчик события Tick:

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    Me.Show()
    ProgressBar1.Visible = True
    Me.Enabled = False
    BackgroundWorker1.RunWorkerAsync()
End Sub

Это делает форму видимой при запуске задания и запускает фонового работника. Установите для свойства BGW WorkerReportsProgress значение True и добавьте 3 обработчика событий:

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    '' Do stuff here, call BackgroundWorker1.ReportProgress to update the PB
End Sub

Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    ProgressBar1.Value = e.ProgressPercentage
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    ProgressBar1.Visible = False
    Me.Enabled = True
    Me.Hide()
End Sub

Вы должны заполнить код для обработчика событий DoWork. Пусть он выполнит эти 15 заданий, обязательно вызовите BackgroundWorker1.ReportProgess, чтобы индикатор выполнения обновлялся. Именно это и делает обработчик событий ProgressChanged. Обработчик события RunWorkerCompleted снова скрывает форму.

Вы можете вызвать метод Show () в событии пункта контекстного меню для NotifyIcon, чтобы пользователь мог снова сделать вашу форму видимой. Вызовите Application.Exit () в пункте контекстного меню, который позволит пользователю выйти из вашего приложения. Убедитесь, что вы отключили это, когда BGW работает. Или реализуйте способ чистой остановки работы.

...