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,598 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

 
LVL 86

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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
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.
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

733 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