Dennis Nowland
Dennis Nowland

Reputation: 21

Communication from Parent thread to child thread

I have a List of threads normally 3 threads each of the threads reference a webbrowser control that communicates with the parent control to populate a datagridview. What I need to do is when the user clicks the button in a datagridviewButtonCell corresponding data will be sent back to the webbrowser control within the child thread that originally communicated with the main thread. but when I try to do this I receive the following error message

'COM object that has been separated from its underlying RCW cannot be used.'

my problem is that I can not figure out how to reference the relevant webbrowser control. I would appreciate any help that anyone can give me.

The language used is c# winforms .Net 4.0 targeted

Code sample:

The following code is executed when user click on the Start button in the main thread

private void StartSubmit(object idx) {

/*

method used by the new thread to initialise a 'myBrowser' inherited from the webbrowser control each submitters object is an a custom Control called 'myBrowser' which holds detail about the function of the object eg:

*/

//index: is an integer value which represents the threads id

int index = (int)idx;

//submitters[index] is an instance of the 'myBrowser' control

submitters[index] = new myBrowser();

//threads integer id

submitters[index]._ThreadNum = index;

// naming convention used 'browser' +the thread index

submitters[index].Name = "browser" + index;

//set list in 'myBrowser' class to hold a copy of the list found in the main thread

submitters[index]._dirs = dirLists[index];

// suppress and javascript errors the may occur in the 'myBrowser' control

submitters[index].ScriptErrorsSuppressed = true;

//execute eventHandler

submitters[index].DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(DocumentCompleted);

//advance to the next un-opened address in datagridview the navigate the that address

//in the 'myBrowser' control.

SetNextDir(submitters[index]);

}

private void btnStart_Click(object sender, EventArgs e) {

  // used to fill list<string> for use in each thread.

  fillDirs();

  //connections is the list<Thread> holding the thread that have been opened
  //1 to 10 maximum

  for (int n = 0; n < (connections.Length); n++)

  {

     //initialise new thread to the StartSubmit method passing parameters

     connections[n] = new Thread(new ParameterizedThreadStart(StartSubmit));

     // naming convention used conn + the threadIndex ie: 'conn1' to 'conn10' 

     connections[n].Name = "conn" + n.ToString();

     // due to the webbrowser control needing to be ran in the single
     //apartment state

     connections[n].SetApartmentState(ApartmentState.STA);

     //start thread passing the threadIndex

     connections[n].Start(n);

  }

}

Once the 'myBrowser' control is fully loaded I am inserting form data into webforms found in webpages loaded via data enter into rows found in the datagridview. Once a user has entered the relevant details into the different areas in the row the can then clicking a DataGridViewButtonCell that has tha collects the data entered and then has to be send back to the corresponding 'myBrowser' object that is found on a child thread.

Thank you

Upvotes: 2

Views: 1253

Answers (2)

prprcupofcoffee
prprcupofcoffee

Reputation: 2970

COM objects are reference-counted (see IUnknown). obj->AddRef increments the reference count and obj->Release() decrements it. When the reference counter reaches zero, the object deallocates its memory and goes away, and that is what has happened when this error occurs.

Dispose doesn't necessarily call Release - the way to do that for a COM object is to call Marshal.ReleaseComObject. Finalizing an object would release it, however. Make sure your web browser control stays in scope, and make sure it isn't actually accessed on any threads other than the main UI thread.

Upvotes: 0

Eric J.
Eric J.

Reputation: 150108

That error indicates that the managed object wrapping the COM object (probably the WebBrowser control, but I can't be sure without more information) has been disposed. That means that the managed object still exists (it has not been garbage collected), but IDisposable.Dispose() has been called on it (which releases the WebBrowser control, which is a COM object).

RCW, by the way, stands for Runtime Callable Wrapper.

Ensure that the COM object you are trying to reference via it's managed wrapper has not had IDisposable.Dispose called on it (directly, or e.g. by leaving the scope of a using block).

Upvotes: 1

Related Questions