Results 1 to 6 of 6

Thread: [RESOLVED] [2005] Simple Threading Probloem

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Mar 2006
    Posts
    19

    Resolved [RESOLVED] [2005] Simple Threading Probloem

    I'm trying to create a pretty easy threaded application but I keep getting an error message:

    Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on.

    I am aware that I should only alter the properties of a control from the thread in which it was created on, but I'm not altering the control directly from another thread. This is my current source:

    VB Code:
    1. Imports System.IO
    2. Imports System.Threading
    3.  
    4. Public Class MainForm
    5.  
    6.     Private WithEvents _pdfMaker As PDFMaker
    7.  
    8.     Private Sub btnBrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBrowse.Click
    9.         If (browseDialog.ShowDialog = Windows.Forms.DialogResult.OK) Then
    10.             txtArchiveFilePath.Text = browseDialog.FileName
    11.         End If
    12.     End Sub
    13.  
    14.     Private Sub btnBurnFiles_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBurnFiles.Click
    15.         _pdfMaker = New PDFMaker
    16.  
    17.         Dim mainThread As Thread = New Thread(AddressOf _pdfMaker.createPdfFromTiffArchive)
    18.         _pdfMaker.ArchivePath = txtArchiveFilePath.Text
    19.         _pdfMaker.TempDir = "C:\test\"
    20.  
    21.         mainThread.Start()
    22.     End Sub
    23.  
    24.  
    25.     Private Sub _pdfMaker_TiffAdded(ByVal percentDone As Double) Handles _pdfMaker.TiffAdded
    26.         currentProgress.Value = percentDone
    27.         txtStatus.Text = "Building PDF File (" & percentDone & "%)"
    28.     End Sub
    29. End Class

    The error message is coming from currentProgress.Value = percentDone. currentProgress is an object of type toolStripProgressBar. For some reason though if i comment that line out the next line: txtStatus.Text = "Building PDF File (" & percentDone & "%)" does not trigger an error... any ideas?

  2. #2
    Fanatic Member Dnereb's Avatar
    Join Date
    Aug 2005
    Location
    Netherlands
    Posts
    863

    Re: [2005] Simple Threading Probloem

    I wouldn't do it that way.

    Create a sepparate class to handle the pdfmaker
    That creates a new instance of Pdfmaker on creation
    and contains a Sub that does the stuff you want it to do (let's call it DoIt).

    for testing just create the class and test if the code is working
    to run it on a sepparate thread do it something like this

    Code:
    Dim  ClsPdf As New PdfClass
    Dim T as Thread
    T  =  New  Thread(AddressOf  ClsPdf.DoIt)
    T.Start()
    Added bonus is the possibility to safely get data from the thread to your main
    program by adding Public Fields in the class like
    Public TiffCreationComplete As Boolean

    You can check in your main program to see if a certain stage in the sepperate thread has been accomplished.
    why can't programmers keep and 31 Oct and 25 dec apart. Why Rating is Useful
    for every question you ask provide an answer on another thread.

  3. #3

    Thread Starter
    Junior Member
    Join Date
    Mar 2006
    Posts
    19

    Re: [2005] Simple Threading Probloem

    Thank you for your response, I'm still a little stuck though. The basic jist of my program is that it's taking in a .zip archive full of tiff files, breaking the the tiff files down into individual frames, and then packing all those frames into a PDF document.

    I've tried to encapsulate that proccess into the "createPdfFromTiffArchive" subroutine within the "PDFMaker" class. The createPdfFromTiffArchive souroutine raises an event, "TiffAdded", everytime a Tiff file has been extracted and added to the PDF file.

    I figured that by encapsulating all the statements needed to to create the PDF file in a single subroutine that i could call this subroutine in a seperate thread and have it run in the backround. That way i could just update the progress bar, "currentProgress", everytime the "tiffAdded" event is raised. I keep getting this cross-thread exception though.

    I figured that the subroutine that handled the "tiffAdded" event was in the same thread that created "currentProgress." Am i wrong in this?

    Are you sugesting that i create a second thread to monitor the status of my other thread?

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: [2005] Simple Threading Probloem

    You have two choices in VB2005 to avoid cross-thread control accesses. You can either use a BackgroundWorker instead of explicitly creating the worker thread. Then you can call the ReportProgress method to raise the ProgressChanged event in the UI thread rather than the worker. This means that the ProgressChanged event handler is executed in the UI thread so you can access controls directly. Alternatively you can use delegation to marshal your control accesses to the UI thread. Here's an example, and ther are many others posted on the forum already.
    VB Code:
    1. Private Delegate Sub SetTextBoxTextDelegate(ByVal text As String)
    2.  
    3. Private Sub SetTextBoxText(ByVal text As String)
    4.     If Me.TextBox1.InvokeRequired Then
    5.         'This is a worker thread so create a delegate to cross the thread boundary.
    6.         Me.TextBox1.Invoke(New SetTextBoxTextDelegate(AddressOf SetTextBoxText), text)
    7.     Else
    8.         'This is the UI thread so access the control's members directly.
    9.         Me.TextBox1.Text = text
    10.     End If
    11. End Sub
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  5. #5
    Junior Member
    Join Date
    Dec 2006
    Posts
    31

    Re: [2005] Simple Threading Probloem

    what are threads? lol

  6. #6

    Thread Starter
    Junior Member
    Join Date
    Mar 2006
    Posts
    19

    Re: [2005] Simple Threading Probloem

    Thanks to both of you, I have it working right now. It took me forever and a day to figure out that you needed to call the invokeRequired method on the ProgressBar class that was encapsulated in the ToolStripProgressBar class. Here is the code if anyone is intrested:

    VB Code:
    1. Imports System.IO
    2. Imports System.Threading
    3.  
    4. Public Class MainForm
    5.  
    6.     Private Delegate Sub setProgressBarDelegate(ByVal value As Double)
    7.     Private WithEvents _pdfMaker As PDFMaker
    8.  
    9.     Private Sub btnBrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBrowse.Click
    10.         If (browseDialog.ShowDialog = Windows.Forms.DialogResult.OK) Then
    11.             txtArchiveFilePath.Text = browseDialog.FileName
    12.         End If
    13.     End Sub
    14.  
    15.     Private Sub btnBurnFiles_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBurnFiles.Click
    16.         _pdfMaker = New PDFMaker
    17.  
    18.         Dim mainThread As Thread = New Thread(AddressOf _pdfMaker.createPdfFromTiffArchive)
    19.         _pdfMaker.ArchivePath = txtArchiveFilePath.Text
    20.         _pdfMaker.TempDir = "C:\test\"
    21.  
    22.         mainThread.Start()
    23.     End Sub
    24.  
    25.     Private Sub _pdfMaker_TiffAdded(ByVal percentDone As Double) Handles _pdfMaker.TiffAdded
    26.         setProgressBar(percentDone)
    27.         txtStatus.Text = "Building PDF File (" & percentDone & "%)"
    28.     End Sub
    29.  
    30.     Private Sub setProgressBar(ByVal value As Double)
    31.         If Me.currentProgress.ProgressBar.InvokeRequired Then
    32.             Me.currentProgress.ProgressBar.Invoke(New setProgressBarDelegate(AddressOf setProgressBar), value)
    33.         Else
    34.             Me.currentProgress.ProgressBar.Value = value
    35.         End If
    36.     End Sub
    37.  
    38. End Class

    @I87
    You can find some general information on threading here : . Basically it's a way to make the CPU do two or more things at once by switching rapidly between differnt tasks.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width