Link to home
Start Free TrialLog in
Avatar of EAK31640GW
EAK31640GW

asked on

Cross Thread operation not valid

I have written a program with multiple threads, the two main ones are the UI threads and the Background worker thread running communications to a serialPort using a IO.MemoryStream...
The problem I am running into is that I am getting the a Cross Thread Operation not valid exception. I have researched this problem but all seem to be refering to assing a value to a control on the UI. I am actually doing the opposite. I need to access the SelectedItem function of a combobox Here is a sample of the code.
//cboSweep is an array of ComboBoxes on my Form.
readMessage.sweep = (short) (cboSweep[chnum - 1].SelectedIndex + 1);

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of eyal_mt
eyal_mt
Flag of Israel image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I recently came across this and that in earlier .NET this happened quite often and was then due to a bug in .NET, not in your code. If you are certain that the error is wrong and that you are right, you can disable this error. Quote from Microsoft:

You can disable this exception by setting the value of the CheckForIllegalCrossThreadCalls property to false. This causes your control to run the same way as it would run under Visual Studio 2003.
At the other hand, the same page also says that you should really try your best to resolve the error before you are going to ignore it, because it is a large chance it is correct:

This exception occurs reliably during debugging and, under some circumstances, at run time. You are strongly advised to fix this problem when you see it. You might see this exception when you debug applications that you wrote with the .NET Framework prior to .NET Framework version 2.0.
To help you with it we would need a part of your code to make the problem reproducible. These errors are sometimes hard to correct and a reproducible example would be great.

-- Abel --
Forgot the reference: http://msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx

but it looks like eyal_mt is right on it, too ;-)
BTW, not sure how the whole code looks like - but a simpler option may be to use one of the onchange events to write the interesting data you need to a shared "safe threaded" variable. This way you will always have the current data without having to access the UI controls.
add the following line into your constructor... hope this will help u...


Control.CheckForIllegalCrossThreadCalls = false;
my point exactly ;)
I would really advise against using Control.CheckForIllegalCrossThreadCalls = false;
The only reason it's there is for debugging purposes, this post talks exactly about why you're not supposed to do that:
http://discuss.joelonsoftware.com/default.asp?dotnet.12.460561.4
Avatar of EAK31640GW
EAK31640GW

ASKER

Thank you all for this info. eval_mt your first link was right on! As was the Static property idea. I have started implementing the logic within my code and everything works as I would like it to except I am getting a compile error that my delegate must declare a body because it is not marked as abstract, extern, pr partial.
What am I missing???

Here is the code:

   delegate void GetSelectedIndexDelegate(int index);
    private static int selectedIndex; 
 
	public virtual bool readChannel(int chnum)
	{
        GetSelectedIndex(chnum);
 
        lock (StateLock)
        {
            readMessage.sweep = (short)SelectedIndex;
        }
 
}
 
  private void GetSelectedIndex(int index)
    {
        if (this.cboSweep[index].InvokeRequired)
        {
 
            Invoke(new GetSelectedIndexDelegate(GetSelectedIndex), new object[] {index});
            return;
        }
        lock (StateLock)
        {
            LoggerReadingPanel.SelectedIndex= cboSweep[index].SelectedIndex;
        }
    }
 
    private static int SelectedIndex
    {
        get
        {
            return selectedIndex;
        }
        set
        {
            selectedIndex = value;
        }
 
    }

Open in new window

I'm not seeing anything that would generate that error in this code.
Is this all the code in the class?
There's a return statement missing from readChannel
and your delegate definition is missing an explicit access level (private I assume)- but that wouldn't give this particular error...
No The class is a windows form and has many functions having to do with events on the form.
The function readChannel does return a value later on based off a returned value from another call to read bytes from a IO.Message stream and update labels on the form. I only placed code relavent to the delegate and CrossThreading issue.
Yes the delegate is private.
The error comes from the infamous squiggly blue line under GetSelectedIndexDelegate in the delegate declaration statement.
The whole error is:
Error      1      'LoggerReadingPanel.GetSelectedIndexDelegate(int)' must declare a body because it is not marked abstract, extern, or partial      C:\Documents and Settings\swintern\My Documents\projects\VWQL.NET\VWQuattroLoggerUI\LoggerReadingPanel.cs      15      18      VWQuattroLoggerUI

I too am at a loss, as the only thing I can find in reference to this type off error deals with Auto-Implemented properties...
I'm using Visual Studio 2008 running my code on MixedPlatform... Ok hold on I just switched to run on any CPU and the error went away and now compiles!
Weird!@
This program is a Java conversion using the MS java to C# Converter, which aparently set it to Mixed Platform mode. I had never checked that until now...