|
-
Nov 20th, 2010, 06:13 PM
#1
Thread Starter
Hyperactive Member
[RESOLVED] Need help with cross-threading
hi all,
i have a program with MDI parent and child. initially, the program will call a child e.g. ChildMain. on this child form, 2 processes are run. the 2nd is ran on a backgroundworker. the backgroundworkder in created through code. the process in the background worker is to create another childform but i'm having problem setting the MDIParent of this child form since VS is saying some sort of cross-thread issue.
below are the codes i'm using.
Code:
Imports Microsoft.VisualBasic
Imports System.Net.NetworkInformation
Public Class CHILDMAIN
Dim strRTOTime As String
Private _Host As String
Public Delegate Sub setTextCallback(ByVal value As String)
Public Property Host()
Get
Return _Host
End Get
Set(ByVal value)
_Host = value
End Set
End Property
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Try
Dim strLine As String = String.Empty
Dim strTime As String = Format(Now, "MM-dd-yyyy hh.mm.ss")
Dim Ping As New Ping
Dim PingOptions As New PingOptions
PingOptions.Ttl = 64
Dim PingReply As PingReply = Ping.Send(_Host, 500)
If PingReply.Status = IPStatus.Success Then
strLine = strTime & " Reply from " & _Host & ": bytes=" & PingReply.Buffer.Length & " time=" & PingReply.RoundtripTime & "ms TTL=" & PingReply.Options.Ttl & vbNewLine
Else
strLine = strTime & " Request timed out" & vbNewLine
strRTOTime = strTime
Timer1.Stop()
Dim bgwTemp As New System.ComponentModel.BackgroundWorker
AddHandler bgwTemp.DoWork, AddressOf DoWork
AddHandler bgwTemp.RunWorkerCompleted, AddressOf RunWorkerCompleted
bgwTemp.RunWorkerAsync()
bgwTemp.Dispose()
End If
rtbLog.AppendText(strLine)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
Dim LogForm As New LOG
LogForm.MdiParent = Me.MdiParent
LogForm.RichTextBox1.AppendText(ReturnShellResults("tracert.exe", _Host))
LogForm.Show()
'setText(vbNewLine)
'setText("Trace Route " & _Host & vbNewLine)
'setText("--------------------------------------------------" & vbNewLine)
'setText(ReturnShellResults("tracert.exe", _Host))
'setText("--------------------------------------------------" & vbNewLine)
'setText(vbNewLine)
End Sub
Private Sub RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
Timer1.Start()
End Sub
Private Sub setText(ByVal value As String)
If rtbLog.InvokeRequired Then
rtbLog.Invoke(New setTextCallback(AddressOf setText), value)
Else
rtbLog.AppendText(value)
End If
End Sub
if i use the following codes it works but i need to set the text on a different richtextbox on a different child form.
Code:
setText(vbNewLine)
setText("Trace Route " & _Host & vbNewLine)
setText("--------------------------------------------------" & vbNewLine)
setText(ReturnShellResults("tracert.exe", _Host))
setText("--------------------------------------------------" & vbNewLine)
setText(vbNewLine)
please help me.
thanks.
VB Version: Microsoft Visual Studio 2008 Professional Edition
.NET Version: Microsoft .NET Framework Version 3.5
OS: Windows XP SP3
-
Nov 20th, 2010, 07:39 PM
#2
Re: Need help with cross-threading
As the name suggests, the whole point of a BackgroundWorker is to do background work. Anything to do with the UI is inherentlly NOT background work. Anything to do with the UI is, by defeinition, foreground work. You do NOT create a form in the DoWork event handler. If you do, that form's handle will be owned by that background thread. As you know, you cannot access a window handle on any thread other than the one that created it. How could you possibly then have a parent form created on one thread contain a child form created on another? The two would obviously have to communicate in some way, which is not possible across the thread boundary.
You need to stop and think this through and determine exactly what is foreground work and what is background work. If you want to display a form, perform some long-running task and display the results in the form, that's fair enough. Only the long-running task is background work though, so that's the only part that gets done in the DoWork event. Creating and displaying the form is foreground work, so you do it before calling RunWorkerAsync. Displaying the results is foreground work, so you do that in the ProgressChanged and/or RunWorkerCompleted event handlers. The number one rule of using a BackgroundWorker is NEVER do anything relating specifically to the UI in the DoWork event handler.
-
Dec 5th, 2010, 10:40 PM
#3
Thread Starter
Hyperactive Member
Re: Need help with cross-threading
thanks for the tip.
i opted to have the background process at form_load instead and it seemed to work.
VB Version: Microsoft Visual Studio 2008 Professional Edition
.NET Version: Microsoft .NET Framework Version 3.5
OS: Windows XP SP3
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|