문제

긴 작업 중에 대기 스크린을 구현하는 일반적인 방법을 찾고 있습니다. 나는 몇 번 전에 스레드를 사용했지만, 나는 그것을 매우 가난하거나 너무 번거 로움 (그리고 복사/붙여 넣기 - 공포!)으로 구현했다는 느낌이 들었습니다.

나는 이것을 가능한 한 일반적이고 단순하게 유지하고 싶기 때문에로드를 구현할 필요가 없습니다. BackgroundWorker모든 종류의 쓰레기를 처리하여 유지하기가 어렵습니다.

여기에 내가하고 싶은 일이 있습니다. 이것은 실제로 가능한/모범 사례/uthing과 다를 수 있습니다 - vb.net, framework 2.0 (익명 방법 없음)을 사용합니다.

  Private Sub HandleBtnClick(sender as Object, e as EventArgs) Handles Button.Click
      LoadingScreen.Show()

      'Do stuff here, this takes a while!'
      Dim Result as Object = DoSomethingTakingALongTime(SomeControl.SelectedObject)

      LoadingScreen.Hide()

      ProcessResults(Result)
  End Sub

응용 프로그램은 이제 완전히 단일 스레드이므로 모든 것이 GUI 스레드에서 실행됩니다. 객체에 액세스 할 수 있어야합니다 DoSomethingTakingALongTime() 크로스 스레드 예외를 얻지 않고. GUI 스레드는 완료하는 데 몇 가지 방법 (오랜 시간이 걸리는)을 기다립니다. LoadingScreen 양식은 반응 형을 유지해야합니다 (애니메이션/진행 상황이 있습니다).

이것은 가능한/좋은 접근 방식입니까, 아니면 이런 식으로 너무 단순한 것을보고 있습니까? 이 문제에 관한 모범 사례는 무엇입니까? 그리고 가장 중요한 것은 어떻게 그러한 시스템을 구현할 수 있습니까? 내가 이미 언급했듯이, 나는 나사산에 대한 경험이 거의 없으므로 부드럽게 해주세요 :-)

도움이 되었습니까?

해결책

문제는 작업자 스레드 데이터를 UI 스레드로 전달하려고 할 때 크로스 스레드 예외를 얻는 것입니다. 당신이해야 할 일은 UI에서 컨트롤을 설정하기 전에 invokequired 및 beginvoke를 점검하여 다음과 같은 오류를 얻지 못하는 것입니다.

Private Sub work_CrossThreadEvent(ByVal sender As Object, ByVal e As System.EventArgs) Handles work.CrossThreadEvent

       If Me.InvokeRequired Then
           Me.BeginInvoke(New EventHandler(AddressOf work_CrossThreadEvent), New Object() {sender, e})
           Return
       End If

      Me.Text = "Cross Thread"

End Sub

그냥 변경하십시오 New EventHandler 사용하는 이벤트 처리기에 참여하십시오.

또한 배경 작업자를 사용하는 것은 작업자 수업에 나쁜 방법이 아니라고 생각합니다. 작업을위한 수업을 만들고 백그라운드 작업자를 사용하여 스레딩 작업을 조금씩 수행합니다.

Public MustInherit Class Worker

    Protected WithEvents worker As BackgroundWorker

    Public Sub New()

        worker = New BackgroundWorker()
        worker.WorkerReportsProgress = True
        worker.WorkerSupportsCancellation = True

    End Sub

    Public Sub Start()

        If (Not worker.IsBusy AndAlso Not worker.CancellationPending) Then
            worker.RunWorkerAsync()
        End If

    End Sub

    Public Sub Cancel()
        If (worker.IsBusy AndAlso Not worker.CancellationPending) Then
            worker.CancelAsync()
        End If
    End Sub

    Protected MustOverride Sub Work()

    Private Sub OnDoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles worker.DoWork
        Work()
    End Sub

    Public Event WorkCompelted As RunWorkerCompletedEventHandler
    Private Sub OnRunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles worker.RunWorkerCompleted
        OnRunWorkerCompleted(e)
    End Sub
    Protected Overridable Sub OnRunWorkerCompleted(ByVal e As RunWorkerCompletedEventArgs)
        RaiseEvent WorkCompelted(Me, e)
    End Sub

    Public Event ProgressChanged As ProgressChangedEventHandler
    Private Sub OnProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles worker.ProgressChanged
        OnProgressChanged(e)
    End Sub
    Protected Overridable Sub OnProgressChanged(ByVal e As ProgressChangedEventArgs)
        RaiseEvent ProgressChanged(Me, e)
    End Sub

End Class

Public Class ActualWork
    Inherits Worker

    Public Event CrossThreadEvent As EventHandler

    Protected Overrides Sub Work()

        'do work here'
        WorkABit()
        worker.ReportProgress(25)

        WorkABit()
        worker.ReportProgress(50)

        WorkABit()
        worker.ReportProgress(75)

        WorkABit()
        worker.ReportProgress(100)

    End Sub

    Private Sub WorkABit()

        If worker.CancellationPending Then Return
        Thread.Sleep(1000)
        RaiseEvent CrossThreadEvent(Me, EventArgs.Empty)

    End Sub

End Class

면책 조항 .. VB와 비트 레슬러리는하지만 아이디어를 얻어야합니다.

다른 팁

스레드에서 application.run (yourform)을 사용하여 원하는 것을 얻으십시오.

어떻게 든 닫기 위해 양식에 신호를 보내야합니다.

나는 당신이 도움이되지 않는 것을 찾지 않기를 바랍니다. 그러나 나는 왜 당신이 스레드 대기 화면을 원하는지 의문을 제기 할 것입니까? 먼저 스레딩을 사용하는 이유는 UI가 반응이 유지되고 긴 작업이 백그라운드에서 수행되기 때문입니다.

그렇지 않으면 Formloading Control에 진행 상황이있을 수 있으며 정기적으로 업데이트 할 수있는 DOMETHINGOMETINGTAMETINGTAMEND가 있습니다. 이것은 스레드가 전혀 필요하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top