在 .NET 4.0 中,我正在处理一个加载时间很长(大约 20 秒)的应用程序,所以我想在加载时应用程序顶部的表单上显示一个嗖嗖的滚动选取框。
由于主 UI 线程正在执行所有数据 UI 元素的加载,我无法让它在单独的线程上执行,所以我最终尝试在新线程上运行表单。我最终将这段代码粘贴在表单本身中,让它在一个新线程上显示出来,如下所示:
Public Class frmWait
Public Property Message As String
Get
Return Me.lblMessage.Text
End Get
Set(value As String)
If Not String.IsNullOrEmpty(value) Then
Me.lblMessage.Text = value
Else
Me.lblMessage.Text = DefaultMessage
End If
End Set
End Property
Private OwnerThread As Thread
Private OwnerForm As Form
Private Const DefaultMessage As String = "しばらくお待ちください..."
Public Sub New(ByVal ParentForm As Form)
InitializeComponent()
Me.Message = DefaultMessage
Me.OwnerForm = ParentForm
End Sub
Public Sub New(ByVal Message As String, ByVal ParentForm As Form)
Call InitializeComponent()
Me.Message = Message
Me.OwnerForm = ParentForm
End Sub
Public Sub ShowOnThread()
' Position the form in the center of the owner
With Me.OwnerForm
Dim ownerCenter As New Point(.Location.X + CInt(.Width / 2), .Location.Y + CInt(.Height / 2))
Me.Location = New Point(ownerCenter.X - CInt(Me.Width / 2), ownerCenter.Y - CInt(Me.Height / 2))
End With
Me.OwnerThread = New Thread(New ThreadStart(AddressOf Me.ShowDialog))
Call Me.OwnerThread.Start()
End Sub
Public Shadows Sub Close()
If Me.OwnerThread IsNot Nothing AndAlso Me.OwnerThread.IsAlive Then
Call Me.OwnerThread.Abort()
Else
Call MyBase.Close()
End If
End Sub
End Class
这可能很笨拙,但我在应用程序的不同位置显示它,所以这似乎是最高效的代码方式......
它实际上工作得很好,但我不时遇到问题,需要一些帮助来解决这些问题。
有时,当表单关闭时,我会收到有关线程以不安全方式中止的错误。
目前我将表单手动放置在表单的中心,我希望它覆盖表单。理想情况下,我希望能够调用
.ShowDialog(ParentForm)
它,但是由于从一种形式到另一种形式的跨线程访问,这当然会引发异常。
任何有关如何解决此问题的建议将不胜感激。因为我对线程几乎一无所知,所以我可能像猴子一样编码,所以如果有更好的方法来完成这项工作,我非常想知道它。
我列出的代码在 VB.NET 中,但 C# 中的答案代码也很好(对于任何过分热心的重新标记者)
更新:
我现在意识到我应该在我的问题中提供更多细节......等待表单实际上不是我显示应用程序的第一个表单。首先是一个登录屏幕。当用户通过身份验证时,登录表单会启动应用程序的主界面,这是实际需要很长时间才能加载的表单。
我在登录表单和主界面之间显示等待表单。我还使用此表单来涵盖用户在主界面上启动的任何长时间运行的任务。