我要找的长时间操作过程中实现待机画面的通用方法。我已经使用线程前几次,但我有我实现它的感觉要么非常糟糕,或者用了太多的麻烦(和复制/粘贴 - 恐怖)。

我想保持这种作为一般和简单越好,所以我不会有实施BackgroundWorkers处理各种垃圾的负荷,使事情很难维持了。

下面是我想做些什么 - 请注意,这可能会从什么实际上可能相差/最佳实践/不管 - 使用VB.NET,框架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线程。你需要做的是检查InvokeRequired和BeginInvoke来对你的UI设置控件之前这样你就不会得到错误,像这样:

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控制进度,并有DoSomethingTakingALongTime定期更新。这根本不需要的线程。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top