Hey,
I'm trying to do something rather something that somehow got a bit complicated on the way.
I wanted to have a loading image in a WPF application while doing some httpwebrequests and finally when all is done, just hide the loading image.
I solved the first problem by using threads. I showed the loading image, then called a thread which handled the httpwebrequests and then after all was done I hid the loading image.
The next problem was to try and get WebBrowser to work. I got this error when trying to use it: ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment.
on this line: System.Windows.Forms.WebBrowser webBrowser1 = new System.Windows.Forms.WebBrowser();
Then, I tried declaring the WebBrowser outside of the threaded function and use the invoke function to use it:
webBrowser.Invoke(new Action(delegate {
//webBrowser.Navigate(lastUrl + url);
webBrowser.Navigate("http://google.com");
content = webBrowser.DocumentText;
}));
All worked smoothly but the only problem is that the webBrowser's properties were all null (could not find google although internet is fine and with httpwebrequest it works fine as well).
Here's the code:
private delegate void GetSubtitlesParameters(string serieName, int season, int episode);
private void GetSubtitles(string serieName, int season, int episode)
{
loading_image.Visibility = Visibility.Visible;
GetSubtitlesParameters getSubtitlesParameters = new GetSubtitlesParameters(GetSubtitlesThread);
getSubtitlesParameters.BeginInvoke(serieName, season, episode, null, null);
}
private void GetSubtitlesThread(string serieName, int season, int episode)
{
System.Windows.Forms.WebBrowser webBrowser1 = new System.Windows.Forms.WebBrowser();
webBrowser1.Navigate("http://google.com");
}
What am I doing wrong?
Loading
Imri BarrPosted Oct 9, 2011, 1:33 PM
I solved the problem by adding the control to my WPF application so it could be accessible by every thread I'm running.
Sam HobbsPosted Oct 8, 2011, 1:08 PM
The reason Invoke is required is that the Windows API for windows is not thread-safe. It is not because of .Net but because .Net must use the Windows API.
Remember that you need to use Invoke if the window (webBrowser1) is in a thread different from the thread that owns it. I assume that you are doing what you are using Invoke for in the thread that created the window, therefore you do not need Invoke for it.
Imri BarrPosted Oct 8, 2011, 4:25 AM
I tried to do what you said but I got this error instead: "Invoke or BeginInvoke cannot be called on a control until the window handle has been created."
On these lines:
webBrowser.Invoke(new Action(delegate {
webBrowser.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);
webBrowser.Navigate(lastUrl + url);
}));
Also, is there a better way of doing what I'm trying to do? Instead of using invoke on a WebBrowser instance?
Thanks again!
Sam HobbsPosted Oct 7, 2011, 11:16 PM
So the best event to handle for that is DocumentCompleted. There are many samples of doing that, including an article I wrote. That event is used so frequently that if you add a WebBrowser control to a form and then double-click on the WebBrowser control then you get a DocumentCompleted as the default event.