Link to home
Start Free TrialLog in
Avatar of stringsandbeyond
stringsandbeyond

asked on

Using WebBrowser2 Interface in Multithreaded application.

david_johns and I are working on an application together.  I had more points available so I am repeating his question with more points to hopefully attract an answer:

We are using a WebBrowser2 interface to do some work for us in our application.  We are trying to introduce multithreading allowing the browser to pick up information in the background and let the user continue using the application.

We seem to lose control of the WebBrowser2 (it will no longer navigate or recieve when one thread that was using it exits and another tries to access it.  The browser is still running, but the WebBrowser2 seems to be a corrupt pointer.

500 points for the person who can figure out how to acess the same WebBrowser2 interface inside of a thread different from the one it was created in or somehow store a reference to the browser itself from which we can restore the WebBrowser2 interface before starting to use it in the second thread.  Thanks for your help.

ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of stringsandbeyond
stringsandbeyond

ASKER

jkr,

Wow!  Thanks for all the great info.  Just one more question before I close this out.  As David mentioned we have developed a class that attempts to make the process of using the browser really easy.  As of yet the class does not have any knowledge about the thread that creates it and the one that is operating it.

I am guessing that the best way to handle it is to create the browser instance in the first thread that needs it and go ahead and call CoMarshalInterThreadInterfaceInStream() in the Open() routine.  Then make an Initialize() function that calls CoIntializeEx() and CoGetInterfaceAndReleaseStream() to get control of the WebBrowser2.  Then make an UnInitialize() function that calls CoUnitialize() and CoMarshalInterThreadInterfaceInStream() again to pass the WebBrowser2 back into the next thread that needs it.  Does this approach seem reasonable?  Will the method crash if the thread that calls CoMarshalInterThreadInterfaceInStream() exits before the interface is passed into the next thread that uses it?

Thanks so much for your help.
>>Does this approach seem reasonable?

Hum, there is no need to multiply call 'CoInitializeEx()' - just do that once when your application starts up or creates a thread (then you need to call it agin in the new thread). Also, there is no need to pass the WebBrowser2 'back' again, once it is marshalled across the thread boundaries, both threads can use it. Just be sure to release the interface in both threads, so the proxy (if any) can be released by the marshaling layer.

>>Will the method crash if the thread that calls CoMarshalInterThreadInterfaceInStream()
>>exits before the interface is passed into the next thread that uses it?

I'd create the interface in the applications main thread and pass it to the others when they 'need' it.

BTW, if you want to avoid all the marshalling hassle, take a look at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/htm/cmi_d2l_5omd.asp ("IGlobalInterfaceTable"), which provides aninterface is an efficient way for a process to store an interface pointer in a memory location that can be accessed from multiple apartments within the process, such as processwide variables and agile (free-threaded marshaled) objects containing interface pointers to other objects (last half of the sentence shamelessly stolen from that page :o)

BTW, on the last issue, see also

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/htm/aptnthrd_4ew5.asp ("Creating the Global Interface Table")

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/htm/aptnthrd_6uat.asp ("When to Use the Global Interface Table")

http://www.microsoft.com/msj/0997/activex0997.aspx ("ActiveX Q&A, MSJ September, 1997 - Apartment Neutrality: The Free Threaded Marshaler and the Global Interface Table")
jkr,

You're the best!  Thanks again.