Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

manipulating controls across threads

Status
Not open for further replies.

gib99

Programmer
Mar 23, 2012
51
0
0
CA
Hello,

I'm trying to do some multithread using Invoke() in order to set the values of Window Form controls, and I need some help.

The situation is this. I have a form on which there are many controls. There is a "connect" button on this form. When this button is clicked, it attempts to connect to a database which can take a while. Therefore, we want to bring up a new form with a progress bar while it is connecting.

I have learned, however, that in order for this form/progress bar to work properly (specifically, to prevent it from hiding behind the main application form and to start animating the progress bar immediately), it needs to run in a separate thread from that which does the database connecting, and specifically it has to run in the main thread while the database connecting work in done in a new thread.

So far, this has not been too difficult. The difficulty comes in when the new thread which does the database connecting has to manipulate the controls on the form (the one with the "connect" button) and I get a cross-thread operation error. This is the part I need some guidance on.

Most examples start with a check on InvokeRequired (like this: if (control.InvokeRequired) { // invoke here }). One of the problems I'm having, however, is that the controls I'm using don't have the InvokeRequired flag (I'm using Telerik controls). So instead I'm trying to detect if I'm on the main thread or not. This may not be the best method, but it's kind of where I'm at right now. It's at this point that I need some guidance on how to manipulate controls from across threads, especially when InvokeRequired is not available.

Here's some of the code I have in place:

Code:
// Function that does the work:
        private void PopulateConnectionNameListView(String currentdatabase, bool mayInvoke = true)
        {

            if (mayInvoke && System.Threading.Thread.CurrentThread.ManagedThreadId != 1) // is this the main thread?
            {
		// Then better invoke:
                this.Invoke(new MethodInvoker(delegate { PopulateConnectionNameListView(currentdatabase, false); }));
                return;
            }

	    // This is the line that requires invoking
            radListViewConnectionName.Items.Clear();
...
}

Code:
	// Here are the worker functions that do the database connecting in the background:
        private void BackgroundWorker_DoWork(object sender, EventArgs e)
        {
            ConnectToSelectedDB(); // This is the main entry point for the work. It will eventually call PopulateConnectionNameListView()
        }

        private void BackgroundWorker_WorkCompleted(object sender, EventArgs e)
        {
        }

Code:
// Here's the button click handler for the connect button:
        private void radButtonConnection_Click(object sender, System.EventArgs e)
        {
            System.ComponentModel.BackgroundWorker bw = new System.ComponentModel.BackgroundWorker();
            bw.DoWork += new System.ComponentModel.DoWorkEventHandler(BackgroundWorker_DoWork);
            bw.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(BackgroundWorker_WorkCompleted);
            bw.RunWorkerAsync();

	    // Here's where I bring up my dialog with the progress bar:
            frmRadWaitDialog waitDialog = new frmRadWaitDialog();
            waitDialog.Show();
        }
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top