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,540 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 30 total points
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 3

Accepted Solution

by:
sr22ger earned 420 total points
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
nope, just needed to add a string to a textbox, sorry for the confusion
0
 
LVL 3

Expert Comment

by:sr22ger
Comment Utility
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
Comment Utility
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
Comment Utility
Sweet - it works! :^)
0
 
LVL 67

Author Comment

by:sirbounty
Comment Utility
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Since .Net 2.0, Visual Basic has made it easy to create a splash screen and set it via the "Splash Screen" drop down in the Project Properties.  A splash screen set in this manner is automatically created, displayed and closed by the framework itsel…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

743 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now