Загрузка GIF иногда зависает - PullRequest
1 голос
/ 25 февраля 2009

Я пытаюсь использовать загрузочный оверлей поверх формы Windows, который добавляет непрозрачный слой на 50% поверх формы Windows с загрузочным GIF, в то время как он делает то, что ему нужно, в фоновом потоке. Наложение - это форма окна, которую я рисую в событии onPaint.

Наложение загрузки отлично работает при нескольких различных формах загрузки, но не работает должным образом при вызове, чтобы обеспечить терпение в течение 30-секундного процесса загрузки (при этом документ Word печатается в PDF, а затем загружается этот PDF на SQL Server). Эта загрузка собирает некоторые данные из формы, помещает их в объект, а затем полностью работает в фоновом потоке. Появится оверлей загрузки, покажет первый кадр загрузки GIF, затем просто остановится. OnPaint запускается, а рамка изображения обновляется, но она не видна

Конструктор устанавливает форму для рисования пользователем:

Sub New()
    InitializeComponent()
    SetStyle(ControlStyles.UserPaint Or ControlStyles.Opaque, True) 
End Sub

Затем в событии Form.Shown вызывается метод ImageAnimator.Animate:

Private Sub LoadingOverlay_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
    If Not currentlyAnimating Then
        ImageAnimator.Animate(animatedImage, AddressOf Me.OnFrameChanged)
        currentlyAnimating = True
    End If
End Sub

Обработчик события onFrameChanged просто делает недействительной форму:

Private Sub OnFrameChanged(ByVal sender As Object, ByVal e As System.EventArgs)
    'Force a call to onPaint
    Me.Invalidate()
End Sub

Затем onPaint переопределяется и выполняет рисование:

Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
    MyBase.OnPaint(e)

    'Get the next frame ready for rendering
    ImageAnimator.UpdateFrames()

    'Draw the next frame in the animation.
    e.Graphics.DrawImage(Me.animatedImage, GetCenter(Me.animatedImage.Size))
    TextRenderer.DrawText(e.Graphics, strStatus, Me.Font, GetTextLocation(Me.animatedImage.Size), Color.White, Color.Black)

End Sub

Наконец, метод ImageAnimator.StopAnimate вызывается в событии закрытия формы:

Private Sub LoadingOverlay_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
    If currentlyAnimating Then
        ImageAnimator.StopAnimate(animatedImage, AddressOf Me.OnFrameChanged)
        currentlyAnimating = False
    End If
End Sub

Вот как вызывается и закрывается оверлей загрузки:

Private Sub ShowLoadingOverlay()
    If Not blnLoadingOverlayVisible Then

        Me.Enabled = False

        patience = New LoadingOverlay()
        patience.Location = Point.Add(parent.PointToScreen(Me.Location), New Size(0, parent.ToolStrip.Height + parent.MenuStrip.Height))
        patience.Size = Me.Size
        patience.Show()
        patience.BringToFront()

        blnLoadingOverlayVisible = True

    End If
End Sub

Private Sub HideLoadingOverlay()
    If blnLoadingOverlayVisible Then
        'Close loading overlay'
        patience.Close()
        patience.Dispose()
        patience = Nothing
        Me.Enabled = True
        blnLoadingOverlayVisible = False
    End If
End Sub

Ответы [ 2 ]

1 голос
/ 25 февраля 2009

"какой-то COM" имеет отношение. Вы попали в квартиру COM потокового правила. COM-объект, такой как Word, должен быть создан в потоке STA. Ваш основной поток пользовательского интерфейса соответствует требованиям, он начинается с Main () и имеет атрибут [STAThread]. Все вызовы методов, которые вы делаете в другом потоке, автоматически передаются COM-потоком в поток STA. Гуммирование вашей анимации.

Это не легко исправить. Вам потребуется фоновый поток, который также должен быть потоком STA, используйте Thread.SetApartmentState (). И прокачайте цикл сообщений, используйте Application.Run (). Начать работу с кодом и выйти из цикла неудобно, попробуйте использовать форму, которая переопределяет SetVisibleCore (), чтобы вы могли не делать его видимым.

0 голосов
/ 25 февраля 2009

Изначально все происходит в одном фоновом потоке. Всего запущено 3 метода. Когда я переместил поток загрузки (который выполняет примерно половину работы) в другой фоновый поток, все было в порядке (не идеально, GIF все еще немного подпрыгивал в начале).

Метод загрузки, который был перемещен во второй фоновый поток, вообще не взаимодействует с потоком GUI, он просто выполняет некоторые операции с COM (словом) и SQL. Короче говоря, это работает, но я до сих пор не знаю почему. Любая идея будет принята с благодарностью!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...