Solved

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

Posted on 2007-03-28
15
1,577 Views
Last Modified: 2008-01-09
How can I correct this?
Using vb.net 2k5

In my sub, I have
Dim t As New Thread(AddressOf ShowHistory)
t.Start()

In ShowHistory sub, it bombs on the .view=view.details line below

 With lsvHistory
            .Clear()
            .View = View.Details
            .Columns.Add("Date", 70, HorizontalAlignment.Left)
            '[....]
0
Comment
Question by:sirbounty
15 Comments
 
LVL 14

Assisted Solution

by:jake072
jake072 earned 50 total points
ID: 18808143
You have to access the thread on which it was created through a delegate, using Invoke.

You'll need to create a Delegate:

Public Delegate Sub DoSomething([Param List])

When your thread needs to access the frmMain:

Dim dlg As New DoSomething(AddressOf DoSomething_Invoke)

Me.Invoke(dlg)

Public Sub DoSomething_Invoke([Param List])

   ' Move your code here

End Sub

Let me know if you need more help,

Jake
0
 
LVL 3

Assisted Solution

by:sr22ger
sr22ger earned 420 total points
ID: 18808272
This is a simple example of using a delegate method if needed to modify a ui control.
Simply call OutputMessage(yourMessage) from the thread needing to modify the text of a control specified in OutputMessage().  This method is nice because it checks whether or not the delegate call is needed, so you don't need to make 2 different methods depending upon where the ui is being modified from.

Private Delegate Sub OutputMessageDelegate(ByVal strMsg As String)
    Private Sub OutputMessage(ByVal strMsg As String)
        If Me.InvokeRequired Then
            ' if operating on a thread, invoke a delegate on the UI thread.
            Dim omd As OutputMessageDelegate = _
            New OutputMessageDelegate(AddressOf OutputMessage)
            Dim aResult As IAsyncResult = Me.BeginInvoke( _
              omd, New Object() {strMsg})
            Me.EndInvoke(aResult)
            Return
        End If
        'do your work here
        someTextBox.Text = strMsg
    End Sub
0
 
LVL 67

Author Comment

by:sirbounty
ID: 18808655
Sorry gang - I'm completely green with creating my own threads...
Still need some help here.

So, if I were, in this example, trying to simply change the listbox's view property to 'viewdetails', I would add the delegate, then the OutputMessage Sub, then....? What?

Presumably I need to remove the .view=view.details from the ShowHistory sub - but what to I place there?  I'm not setting any string, so I'm 'guessing' the delegate would need to be altered?
0
Best Practices: Disaster Recovery Testing

Besides backup, any IT division should have a disaster recovery plan. You will find a few tips below relating to the development of such a plan and to what issues one should pay special attention in the course of backup planning.

 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 30 total points
ID: 18808664
You can also "cheat" and disable that type of checking:
http://msdn2.microsoft.com/en-us/library/system.windows.forms.control.checkforillegalcrossthreadcalls(VS.80).aspx

Usage (in your form load event):
   
    Me.CheckForIllegalCrossThreadCalls = False

But only use that if you have ONE other thread making updates on your UI.  If you have multiple threads then you really should be using Delegates/Invoke as the others suggest.
0
 
LVL 67

Author Comment

by:sirbounty
ID: 18808672
Hmm - thought it was going to work, but then it bombed with the same error on the next line...So 'all' changes to this control will need to be moved to the OutputMessage sub?
0
 
LVL 67

Author Comment

by:sirbounty
ID: 18808717
Yeah, I already found the msdn article...didn't want to cheat this time around... :^)

I'll have at least two...probably more.

I'm trying to have these subs take off on their own...right now my form is locked when these calls are made.  I want the user to be able to fill in a couple of text boxes while they wait...

I'd like to implement this on a couple of functions in my modules too - but will ask a seperate question on that once this is sorted.
0
 
LVL 67

Author Comment

by:sirbounty
ID: 18808727
I 'think' it's working...did I do it right?

    Sub ShowHistory()
        'I've removed 'everything' from here and moved it to OutputMessage (under your test for Invokerequired)
        OutputMessage("Hello") 'But I'm confused on the string...what's the point? : \
    End Sub

So, should I have moved 'all' processing into that delegate?
0
 
LVL 3

Accepted Solution

by:
sr22ger earned 420 total points
ID: 18808730
Here, lets start over using your example not mine.
In your starting method
Dim t As New Thread(AddressOf StartThread)
t.Start()

Sub StartThread
    ShowHIstory()
End Sub

Private DelegateSub ShowHIstoryDelegate()
Private Sub ShowHistory()
If Me.InvokeRequired Then
            ' if operating on a thread, invoke a delegate on the UI thread.
            Dim shd As ShowHistoryDelegate = _
            New ShowHistoryDelegate(AddressOf ShowHistory)
            Dim aResult As IAsyncResult = Me.BeginInvoke( _
              shd, New Object() {strMsg})
            Me.EndInvoke(aResult)
            Return
        End If
        'do your work here
        With lsvHistory
            .Clear()
            .View = View.Details
            .Columns.Add("Date", 70, HorizontalAlignment.Left)
            '[....]
End Sub
0
 
LVL 67

Author Comment

by:sirbounty
ID: 18808743
I think with that last confirmation, I'm all set...I removed the string requirements - would like to know if they're needed (probably for just passing simple text to a textbox?)

As a followup - if I was creating 'another' thread - I'd need another delegate sub and related sub to process that, correct?
0
 
LVL 67

Author Comment

by:sirbounty
ID: 18808761
Okay, great...so going off what you've posted...could that same methodology be used for different threads?
Something like:

Dim t As New Thread(AddressOf StartThread)
t.Start()

Sub StartThread (caller?)
   If caller=History Then
     ShowHIstory()
   Else
     ShowSomethingElse
  End If
End Sub

Or would I need something specific for each thread?
0
 
LVL 3

Assisted Solution

by:sr22ger
sr22ger earned 420 total points
ID: 18808764
nope, just needed to add a string to a textbox, sorry for the confusion
0
 
LVL 3

Expert Comment

by:sr22ger
ID: 18808795
not sure what you mean by the last question. If I am catching you right, Yes that would work fine.  You can call ShowHistory from any thread.
0
 
LVL 67

Author Comment

by:sirbounty
ID: 18808840
I'm not sure what I'm saying either...doing it will prove it to me.
Thanx much for the info!
0
 
LVL 67

Author Comment

by:sirbounty
ID: 18808980
Sweet - it works! :^)
0
 
LVL 67

Author Comment

by:sirbounty
ID: 18809125
If you're interesting in helping me again, along the same lines...
http://www.experts-exchange.com/Programming/Languages/.NET/Visual_Basic.NET/Q_22477954.html
0

Featured Post

Enterprise Mobility and BYOD For Dummies

Like “For Dummies” books, you can read this in whatever order you choose and learn about mobility and BYOD; and how to put a competitive mobile infrastructure in place. Developed for SMBs and large enterprises alike, you will find helpful use cases, planning, and implementation.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
1.0 - Introduction Converting Visual Basic 6.0 (VB6) to Visual Basic 2008+ (VB.NET). If ever there was a subject full of murkiness and bad decisions, it is this one!   The first problem seems to be that people considering this task of converting…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question