none
Control.Invoke must be used to interact with controls created on a separate thread.

    General discussion

  • I am making a stock taking application in a smart device projec tin Visual Studio 2010. What i want to do is create a thread for when i want to update the database(csv file) and use a status control to show the user what is happening ("connecting", "saved", "error") etc.

     

    However when i try to call a function from within my save method whcih is running on a thread i get a Control.Invoke must be used to interact with controls created on a separate thread error at runtime.

        private void btnUpdateStock_Click(object sender, EventArgs e)
        {
          if (this.txtStock.ReadOnly == false && notSaving)
          {
            Product p = dataManager.getCurrentProduct();
            p.unitsInStock = Int32.Parse(this.txtStock.Text);
    
            Thread saveThread = new Thread(new ThreadStart(saveItems));
            saveThread.Start();
    
          }
    
        }
        public void saveItems()
        {
          this.statusSave.Text = "Connecting to Database";
    
          //ERROR OCCURS HERE
          if (dataManager.saveItems())
          {
            this.statusSave.Text = "Saved to Database";
          }
          else
          {
            this.statusSave.Text = "error";
          }
        }
    

    Any ideas? im fairly new to C# and mobile applications

     

    Thursday, April 14, 2011 6:24 AM

All replies

  • This happens simply because controls such as Textboxes and Buttons only can be accessed by the thread that created them. Usually its the main (or UI) thread that creates the controls. If you want to call methods or access control properties from a worker thread you must invoke that call on the main thread.
    For instance, to set the text for statusSave you can define a method for updating status and use Control.Invoke(...) to marshal call to the proper thread such as

    		private void UpdateStatus(string status)
    		{
    			Control ctl = this.statusSave;
    			if (ctl.InvokeRequired)
    			{
    				ctl.Invoke(new Action<string>(this.UpdateStatus), status);
    			}
    			else
    			{
    				ctl.Text = status;
    			}
    		}
    

    /Calle


    - Still confused, but on a higher level -
    Thursday, April 14, 2011 7:21 AM
  • Thankyou, I had been looking at very similar code to what you put up, however i was trying to udnerstand the importance of it as i thought the problem was with my method call, not my call to change the properties of my control. I know the error should have told me that, but even with it stating one thing, my mind was in another place as the error was highlighting my method call.

     

    After i replaced my code of:

    this.statusSave.Text = "Blah";

     

    to:

    this.statusSave.Invoke(new updateStatusDelegate(this.UpdateStatus),

                                        new object[] { "Connecting to Database" });

    everything works perfectly.

     

    Thursday, April 14, 2011 8:00 AM