0

Possible Duplicate:
Cross-thread operation not valid

I have a problem with using of threading in my application below are the two simple methods and this two methods are called on a button click.
I want to first run the inserting method and thread sleep for 5 seconds after 5 seconds second method run and display according to the coding.
But I face this error:

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

Here's the code:

private void button1_Click(object sender, EventArgs e)

    {

        Thread obj = new Thread(new ThreadStart(inserting));

        Thread obj1 = new Thread(new ThreadStart(insert));

        obj.Start();

        obj1.Start();

    }

public void inserting()
    {
        lblDisplay.Text = "inserting record......";
        Thread.Sleep(5000);
    }
    public void insert()
    {
        lblDisplay.Text = "Record successfully inserted";
    }
Community
  • 1
  • 1
aamankhaan
  • 491
  • 1
  • 9
  • 35

4 Answers4

2

You can only modifiy controls on the same thread as you created them. Use Control.Invoke to modify your control:

lblDisplay.Invoke(() =>
{
    lblDisplay.Text = "inserting record......";
});
Fox32
  • 13,126
  • 9
  • 50
  • 71
1

You are getting the error because you cannot access UI elements on threads other than the main UI thread (or Dispatcher thread in WPF). If you wish to have some status update system, you would be better off having the process(es) running on a separate thread, that then call back onto the main UI thread to update the status text. For example:

public void button1_Click(object sender, EventArgs e)
{
    var thread = new Thread(new ThreadStart(Execute));
    thread.Start();
}

private void Execute()
{
    UpdateStatus("Starting execution...");

    // ... Run some code ...

    UpdateStatus("Inserting record...");

    // Sleep for 5 seconds
    Thread.Sleep(5000);

    // ... Run record insertion code ...

    UpdateStatus("Record successfully inserted");
}

private void UpdateStatus(string status)
{
    // Make sure we're running on the UI thread
    if (this.InvokeRequired)
    {
        BeginInvoke(new Action<string>(UpdateStatus), status);
        return;
    }

    // Update the display text now we are running on the UI thread
    lblDisplay.Text = status;
}

Note: This is an answer specific to WinForms. For WPF, you use CheckAccess() instead of InvokeRequired and this.Dispatcher.BeginInvoke(...) instead of BeginInvoke(...).

Samuel Slade
  • 8,405
  • 6
  • 33
  • 55
0

The lblDisplay was created on another thread, so you need a delegate to change the value. Have a look at the MSDN with an example of what to do.

Matten
  • 17,365
  • 2
  • 42
  • 64
0

I also ran through this problem. I posted the solution here.

This happens because, you trying to modify UI Control, by a thread which didn't create the Control.

Create a Extension like this

public static class ControlExtensions
{
    public static void Invoke(this Control control, Action action)
    {
        if (control.InvokeRequired) control.Invoke(new MethodInvoker(action), null);
        else action.Invoke();
    }
 }

and then do this

lblDisplay.Invoke(() => { lblDisplay.Text = "Record successfully inserted"; }); 

Hope this helps you.

Amar Palsapure
  • 9,590
  • 1
  • 27
  • 46