Crossthread exception and invokerequired solution doesn't change my control value
Posted
by
Pilouk
on Stack Overflow
See other posts from Stack Overflow
or by Pilouk
Published on 2013-10-24T20:01:46Z
Indexed on
2013/10/25
15:54 UTC
Read the original article
Hit count: 170
EDIT Solution :
Here i'm setting my byref value in each object then i'm running a backgroundworker
Private Sub TelechargeFichier()
Dim DocManquant As Boolean = False
Dim docName As String = ""
Dim lg As String = ""
Dim telechargementFini As Boolean = False
lblMessage.Text = EasyDealChangeLanguage.Instance.GetStringFromResourceName("1478")
prgBar.Maximum = m_listeFichiers.Count
For i As Integer = 0 To m_listeFichiers.Count - 1
m_listeFichiers(i).Set_ByRefLabel(lblMessage)
m_listeFichiers(i).Set_ByRefPrgbar(prgBar)
m_listeThreads.Add(New Thread(AddressOf m_listeFichiers(i).DownloadMe))
Next
m_bgWorker = New BackgroundWorker
m_bgWorker.WorkerReportsProgress = True
AddHandler m_bgWorker.DoWork, AddressOf DownloadFiles
m_bgWorker.RunWorkerAsync()
''Completed
'lblMessage.Text = EasyDealChangeLanguage.Instance.GetStringFromResourceName("1383")
'Me.DialogResult = System.Windows.Forms.DialogResult.OK
End Sub
Here is my downloadFiles function : Note that each start will do the downloadMe function see below too
Private Sub DownloadFiles(sender As Object, e As DoWorkEventArgs)
For i As Integer = 0 To m_listeThreads.Count - 1
m_listeThreads(i).Start()
Next
For i As Integer = 0 To m_listeThreads.Count - 1
m_listeThreads(i).Join()
Next
End Sub
I have multiple thread that each will download a ftp file. I would like that each file that have been completed will set a value to a progress bar and a label from my UI thread. For some reason invokerequired never change to false.
Here is my little function that start all the thread
Private Sub TelechargeFichier()
Dim DocManquant As Boolean = False
Dim docName As String = ""
Dim lg As String = ""
Dim telechargementFini As Boolean = False
lblMessage.Text = EasyDealChangeLanguage.Instance.GetStringFromResourceName("1478")
prgBar.Maximum = m_listeFichiers.Count
For i As Integer = 0 To m_listeFichiers.Count - 1
m_listeFichiers(i).Set_ByRefLabel(lblMessage)
m_listeFichiers(i).Set_ByRefPrgbar(prgBar)
m_listeThreads.Add(New Thread(AddressOf m_listeFichiers(i).DownloadMe))
Next
For i As Integer = 0 To m_listeThreads.Count - 1
m_listeThreads(i).Start()
Next
For i As Integer = 0 To m_listeThreads.Count - 1
m_listeThreads(i).Join()
Next
'Completed
lblMessage.Text = EasyDealChangeLanguage.Instance.GetStringFromResourceName("1383")
Me.DialogResult = System.Windows.Forms.DialogResult.OK
End Sub
Here my property that hold the Byref control from the UI thread. This is in my object which content the addressof function that will download the file (DownloadMe)
Public Sub Set_ByRefPrgbar(ByRef prgbar As ProgressBar)
m_prgBar = prgbar
End Sub
Public Sub Set_ByRefLabel(ByRef lbl As EasyDeal.Controls.EasyDealLabel3D)
m_lblMessage = lbl
End Sub
Here is the download function :
Public Sub DownloadMe()
Dim ftpReq As FtpWebRequest
Dim ftpResp As FtpWebResponse = Nothing
Dim streamInput As Stream
Dim fileStreamOutput As FileStream
Try
ftpReq = CType(WebRequest.Create(EasyDeal.Controls.Common.FTP_CONNECTION & m_downloadFtpPath & m_filename), FtpWebRequest)
ftpReq.Credentials = New NetworkCredential(FTP_USER, FTP_PASS)
ftpReq.Method = WebRequestMethods.Ftp.DownloadFile
ftpResp = ftpReq.GetResponse
streamInput = ftpResp.GetResponseStream()
fileStreamOutput = New FileStream(m_outputPath, FileMode.Create, FileAccess.ReadWrite)
ReadWriteStream(streamInput, fileStreamOutput)
Catch ex As Exception
'Au pire la fichier sera pas downloader
Finally
If ftpResp IsNot Nothing Then
ftpResp.Close()
End If
Dim nomFichier As String = m_displaynameEN
If EasyDealChangeLanguage.GetCurrentLanguageTypes = EasyDealChangeLanguage.EnumLanguageType.Francais Then
nomFichier = m_displaynameFR
End If
If m_lblMessage IsNot Nothing Then
EasyDealCommon.TH_SetControlText(m_lblMessage, String.Format(EasyDealChangeLanguage.Instance.GetStringFromResourceName("1479"), nomFichier))
End If
If m_prgBar IsNot Nothing Then
EasyDealCommon.TH_SetPrgValue(m_prgBar, 1)
End If
End Try
End Sub
Here is the crossthread invoke solution function :
Public Sub TH_SetControlText(ByVal ctl As Control, ByVal text As String)
If ctl.InvokeRequired Then
ctl.BeginInvoke(New Action(Of Control, String)(AddressOf TH_SetControlText), ctl, text)
Else
ctl.Text = text
End If
End Sub
Public Sub TH_SetPrgValue(ByVal prg As ProgressBar, ByVal value As Integer)
If prg.InvokeRequired Then
prg.BeginInvoke(New Action(Of ProgressBar, Integer)(AddressOf TH_SetPrgValue), prg, value)
Else
prg.Value += value
End If
End Sub
The problem is the invokerequired never get to false it actually goes in to beginInvoke but never end in the Else section to set the value.
© Stack Overflow or respective owner