Threading Question

A

Aaron

Hi,

1. Can a seperate thread create a form?

I created some test code. I have a sub Test that attempts to create
and show a form, objFrmTest which is of type frmTest. Button1 and
Button2 exist on another form (not frmTest). Button1 attempts to run
sub Test with another thread, which Button2 simply attempts to run sub
Test. The results, in short, are the Button1 does not work while
Button2 does. Also, once Button1 is run, neither will work properly
there after.

I setup some breakpoints and did found that in both cases, the creating
thread sucessfully ran both the form constructor and the Load event.
In spite of that though, Button1 cannot bring up frmTest.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim thdTest As Thread
thdTest = New Thread(AddressOf Test)
thdTest.Name = "ThreadTest"
thdTest.Priority = ThreadPriority.Highest
thdTest.Start()
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
Test()
End Sub

Public Sub Test()
If objFrmDiscrepancy Is Nothing Then
objFrmDiscrepancy = New frmDiscrepancy
ElseIf objFrmDiscrepancy.IsDisposed Then
objFrmDiscrepancy = Nothing
objFrmDiscrepancy = New frmDiscrepancy
End If

objFrmDiscrepancy.Show()
objFrmDiscrepancy.WindowState = FormWindowState.Normal
End Sub

2. Assuming that a thread can create a form, will all the event
handlers on the form execute against the primary thread (default
thread? application thread?) or the thread that created it?

3. Can a form be configured such that the user cannot click on any
other forms within the application without first closing said form
(Similar to a message box), w/ or w/o multithreading?

Thanks,
Aaron
 
T

Tom Shelton

Aaron said:
Hi,

1. Can a seperate thread create a form?

I created some test code. I have a sub Test that attempts to create
and show a form, objFrmTest which is of type frmTest. Button1 and
Button2 exist on another form (not frmTest). Button1 attempts to run
sub Test with another thread, which Button2 simply attempts to run sub
Test. The results, in short, are the Button1 does not work while
Button2 does. Also, once Button1 is run, neither will work properly
there after.

I setup some breakpoints and did found that in both cases, the creating
thread sucessfully ran both the form constructor and the Load event.
In spite of that though, Button1 cannot bring up frmTest.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim thdTest As Thread
thdTest = New Thread(AddressOf Test)
thdTest.Name = "ThreadTest"
thdTest.Priority = ThreadPriority.Highest
thdTest.Start()
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
Test()
End Sub

Public Sub Test()
If objFrmDiscrepancy Is Nothing Then
objFrmDiscrepancy = New frmDiscrepancy
ElseIf objFrmDiscrepancy.IsDisposed Then
objFrmDiscrepancy = Nothing
objFrmDiscrepancy = New frmDiscrepancy
End If

objFrmDiscrepancy.Show()
objFrmDiscrepancy.WindowState = FormWindowState.Normal
End Sub

It sure is - but you need to have a message pump on the second thread,
or the form will simply exit (Application.Run), see my example code
below (note - if you remove the call to thrd.IsBackground, the child
forms will continue to run even when you close form1):

' Form1
Option Strict On
Option Explicit On

Imports System
Imports System.Threading

Public Class Form1
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As
Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form
Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents Button1 As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button
Me.SuspendLayout()
'
'Button1
'
Me.Button1.Dock = System.Windows.Forms.DockStyle.Fill
Me.Button1.Location = New System.Drawing.Point(0, 0)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(216, 70)
Me.Button1.TabIndex = 0
Me.Button1.Text = "Button1"
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(216, 70)
Me.Controls.Add(Me.Button1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)

End Sub

#End Region

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim thrd As New Thread(AddressOf ShowForm2)
thrd.IsBackground = True
thrd.Start()
End Sub

Private Sub ShowForm2()
Application.Run(New Form2)
End Sub
End Class

' form2
Public Class Form2
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As
Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form
Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
'
'Form2
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 122)
Me.Name = "Form2"
Me.Text = "Form2"

End Sub

#End Region

End Class

2. Assuming that a thread can create a form, will all the event
handlers on the form execute against the primary thread (default
thread? application thread?) or the thread that created it?

On the thread that the form is on - since that is where the messag pump
lives.
3. Can a form be configured such that the user cannot click on any
other forms within the application without first closing said form
(Similar to a message box), w/ or w/o multithreading?

Sure, form.ShowDialog... Of course, this will only be thread modal :)
If you use showdialog on a secondary thread, it will only block forms
on that thread.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top