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: 140

Filed under:
|
|

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

Related posts about vb.net

Related posts about multithreading