Click here to Skip to main content
16,012,468 members
Please Sign up or sign in to vote.
4.00/5 (3 votes)
See more:
Hi Everybody,
I am new to event handling. what I have done is
Made an event on the Class1
triggered the event in some function in Class1

when I use the event in Form1 , I can't use the Form1 Controls in the function of Form1 called by the event handler.
the following messege occurs
Cross-thread operation not valid: Control 'lblTagID' accessed from a thread other than the thread it was created on.

If I can't use the event created by me in the main form then how we can use the form control events quite easily.
This problem is killing me.
I will appriciate if somebody have a quick answer.
Thank You
Posted

You cant access controls created on other thread directly from a thread.
You need to call a method of the main thread which will update controls for you.

Create a method which you need to update the control. Invoke that method from the event handler. Say your method name is xyz() then call using :

SynchronizationContext context = SynchronizationContext.Current;
if(context == null)
   context = new SynchronizationContext();
context.Send(new SendOrPostCallback( (s) =>; xyz()), null);


You might also use :
C#
BeginInvoke(new MethodInvoker(delegate
{
     xyz();
}));



This will work for you. :rose:
 
Share this answer
 
Comments
pavan986 29-Feb-12 2:46am    
Awesome this post really help for CrossThreadException.

By Pavan
You can call Thread.Sleep Metod

C#
Thread.Sleep(100);
this.Invoke((MethodInvoker)delegate
{

    myTextBox.Text += strMessage + "\r\n";
});
 
Share this answer
 
v2
Your problem is that you're accessing a control on the form with another thread. DotNet doesn't let you do that unless you "take steps" to allow it. There is a property you can set, but that's considered bad practice. The more appropriate method is to use Invoke.

I'll let you do the research to get the particulars. After all, this *is* supposed to be a quick answer.

Hint: Google "Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException" and see what you get.
 
Share this answer
 
using System;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    // DPM: 03/23/13.  Building on John Simmons excellent comment above, here is one simple example using similar tools. 
    // Create a simple Form with a single textbox called myTextBox.
    // Use System Timer Thread to flash myTextBox contents.
    // Could used to alert the user the app. is running when a longer method is executing.
    // for example: loading a grid, preparing a report, getting a traceroute trace, etc.

    // Requires cross thread communication.
    // Use a delegate and an invoke statement to allow a method in the Form to change controls in the Form.  
    // C# does NOT allow cross thread access directly to controls!!!

    // You can't access controls created on other thread directly from a thread. 
    // You need to call a method of the main thread which will update controls for you. 

 
    // Add try/catch to debug/follow execution.
    // REF:http://msdn.microsoft.com/en-us/library/0b1bf3y3(v=vs.100).aspx
    // REF:http://www.codeproject.com/Questions/54201/Text-threw-an-exception-of-type-Microsoft-VisualSt
    public partial class frmMain : Form
    {
        public delegate void InvokeDelegate();              // Delegate for Cross thread access from timer thread to form thread.
        public System.Threading.Timer timer;                // Timer thread.

        public frmMain()
        {
            InitializeComponent();
            runTimer();                                     // Start Timer.
        }

        /// Create Timer Thread.
        /// REF:http://msdn.microsoft.com/en-us/library/saba8ksx(v=vs.100).aspx
        public void runTimer()
        {
            try
            {
                int timeout = Timeout.Infinite;
                int interval = 1000;
                TimerCallback callback = new TimerCallback(InvokeMethod);       // Method to call on each timer event.
                System.Threading.Timer timer = new System.Threading.Timer(callback, null, timeout, interval);
                timer.Change(0, 1000);                                          // Changes the start time and the interval between method invocations for a timer.
            }

            catch (Exception e)
            {
                MessageBox.Show("runTimer: " + e.ToString());
            }
        }

        /// Action for each timer event.
        /// NOTE: State Object needed for callback communication.
        public void InvokeMethod(Object state)
        {
            try
            {
                myTextBox.BeginInvoke(new InvokeDelegate(FlashBox));        // Set Form method to perform changes on Form.
            }

            catch (Exception e)
            {
                MessageBox.Show("InvokeMethod: " + e.ToString());
            }
        }

        /// Method to change Form controls.
        public void FlashBox()
        {
            try
            {
                myTextBox.Text = (string.IsNullOrEmpty(myTextBox.Text)) ? "Executed the given delegate" : string.Empty;
            }

            catch (Exception e)
            {
                MessageBox.Show("FlashBox: " + e.ToString());
            }
        }
    }
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900