In .NET 4.0 I'm dealing with an app which has a long loading time (about 20 seconds), so I wanted to display a swish scrolling marquee on a form that comes on top of the application whilst it is loading.
Since the main UI thread is doing all the loading of data UI elements, I couldn't get that to execute on a separate thread, so I ended up trying to run the form on a new thread. I ended up sticking this code in the form itself, to have it show itself on a new thread, like this:
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
This is probably quite clumsy, but I am showing it in different places in the application, so this seemed the most code-efficient way of doing this...
It actually works quite well, but I am encountering problems from time to time with this and need some help on how to address these issues.
Sometimes when the form gets closed I get an error about the thread being aborted in an unsafe manner.
At the moment I position the form manually in the centre of the form I want it to cover form. Ideally I'd like to be able to call
.ShowDialog(ParentForm)
on it, but of course that raises an exception because of cross-thread access from one form to the other.
Any suggestions on how to resolve this would be most appreciated. Because I know virtually nothing about threading I probably coded this like a monkey, so if there is a better method to get this done, I would very much like to know about it.
The code I list is in VB.NET, but answer code in C# is fine too (for any overzealous retaggers)
UPDATE:
I realise now that I should have given a lot more details in my question... The wait form is actually not the first form I am displaying the app. There first is a login screen. When the user is authenticated, the login form launches the main interface of the app, which is the form which actually takes a long time to load.
I am displaying the wait form in between the login form and the main interface. I also use this form to cover for any long running tasks launched on the main interface by the user.