gpt4 book ai didi

.net - 线程加载(等待)屏幕

转载 作者:行者123 更新时间:2023-12-01 01:38:19 25 4
gpt4 key购买 nike

我正在寻找一种通用方法来在长时间操作期间实现等待屏幕。我之前使用过几次线程,但我觉得我实现它要么非常糟糕,要么太麻烦(和复制/粘贴 - 恐怖!)。

我想让它尽可能通用和简单,所以我不必实现 BackgroundWorker 的负载。处理各种垃圾,使事情难以维护。

这是我想要做的——请注意,这可能与实际可行的/最佳实践/任何不同的——使用 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表单应该保持响应(它是动画的/有一个进度条/等等)。

这是一个可行/好的方法还是我认为这种方式过于简单?关于这个问题的最佳做法是什么?最重要的是:我如何实现这样的系统?正如我已经提到的,我对线程的经验很少,所以请保持温和:-)

最佳答案

您的问题是,当您尝试将 Worker 线程数据传递给 ui 线程时,会出现跨线程异常。你需要做的是在你的 ui 上设置控件之前检查 InvokeRequired 和 begininvoke 这样你就不会得到这样的错误:

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部分到您使用的事件处理程序。

此外,我认为使用后台工作人员对您的工作人员类(class)来说并不是一个坏方法,
只需为您的工作创建一个类,并使用后台工作人员来执行如下线程处理:
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 有点生疏,但你应该明白。

关于.net - 线程加载(等待)屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/316940/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com