VB.Net: понимание того, как работает Application.Run()

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

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

Это вызывает несколько вопросов:

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

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


    person Clément    schedule 04.11.2010    source источник


    Ответы (1)


    Поместите 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
    

    Это делает форму видимой при запуске задания и запускает фонового рабочего. Установите для свойства WorkerReportsProgress BGW значение 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 работает. Или реализовать способ чистой остановки задания.

    person Hans Passant    schedule 04.11.2010
    comment
    Ганс, ты определенно молодец =) Спасибо за очень подробный и полный ответ. респект вам :) - person Clément; 05.11.2010