Hi,
im Form_Main wird ein Link (URL) erstellt, der an Form_Web übergeben wird. Im Form_WSeb läuft ein Webbrowser. Diesen möchte ich aber im Backgroundworker ausführen, damit der Nutzer Form_Main weiterhin nutzen kann.
Ohne Backgroundworker funktioniert mein Code, nur mit erhalte ich folgende Fehlermeldung:
Fehlermeldung:
Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement webBrowser1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde
Mein Code:
public partial class Form_Web : Form
{
private string F2_Request_URL;
String Url = string.Empty;
BackgroundWorker worker_MaWeBro;
public Form_Web(string F1_Request_URL)
{
InitializeComponent();
F2_Request_URL = F1_Request_URL;
Url = F2_Request_URL;
//Url = "http://malabrequest/MalabDetailedRequest.aspx?RequestId=2028408_TEM";
label1.Text = Url;
worker_MaWeBro = new BackgroundWorker();
worker_MaWeBro.WorkerReportsProgress = true;
worker_MaWeBro.WorkerSupportsCancellation = true;
worker_MaWeBro.DoWork += new DoWorkEventHandler(worker_MaWeBro_DoWork);
worker_MaWeBro.RunWorkerAsync();
}
private void Form_Web_Load(object sender, EventArgs e)
{
Cmd_Browser_Back.Enabled = false;
Cmd_Browser_Home.Enabled = false;
}
void worker_MaWeBro_DoWork(object sender, DoWorkEventArgs e)
{
MaWeb_Browser();
}
private void MaWeb_Browser()
{
if (toolStripComboBox1.Text != "")
Url = toolStripComboBox1.Text;
webBrowser1.Navigate(Url);
webBrowser1.ProgressChanged += new WebBrowserProgressChangedEventHandler(webpage_ProgressChanged);
webBrowser1.DocumentTitleChanged += new EventHandler(webpage_DocumentTitleChanged);
webBrowser1.StatusTextChanged += new EventHandler(webpage_StatusTextChanged);
webBrowser1.Navigated += new WebBrowserNavigatedEventHandler(webpage_Navigated);
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webpage_DocumentCompleted);
}
Google und FAQ haben mir leider nicht auf die Sprünge geholfen 😦
Sorry, das ist nicht möglich. Alle UI-Elemente müssen im Main UI-Thread ausgeführt werden.
Du kannst mit dem BackgroundWorker
nur Berechnungen o.ä. durchführen.
Um einzelne UI-Funktionalitäten an den UI-Thread zu delegieren, s. [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke).
Jedoch würde dein Code (auch ohne die Fehlermeldung) nicht so funktionieren, da die Methode MaWeb_Browser
sich sofort beendet (da Navigate()
nicht-blockierend ist und ja extra auf DocumentCompleted
gewartet werden soll).
Aber genau für diese Funktionalität brauchst du ja keinen Backgroundworker
, da der WebBrowser
das asynchrone Arbeiten ja selber schon unterstützt.
Du solltest jedoch die Zeilen bzgl. Navigate
und dem Abonnieren der Ereignismethoden vertauschen (bzw. letzteres nur einmalig im Konstruktor bzw. Designer durchführen).
Ok, danke für den Tipp.
Gibt es denn eine andere Möglichkeit den Browser vom Form_Main "abzukoppeln", sodass man das Main während geöffneten Browser-Form nutzen kann?
Du solltest die WebBrowser Komponente gar nicht mehr verwenden, weil sie auf eine seit Jahren nicht mehr unterstützten IE Version basiert.
Zwar war das eine zeitlang von der IE Version in der Registy abhängig und damit von der IE Version des jeweiligen PCs - doch ist die letzte Version des Browser Controls der IE8.
Du solltest Dir hier allgemein Alternativen suchen, zB https://github.com/cefsharp/CefSharp
Aber nein, den Wunsch nach Entkoppeln gibt es hier nicht; so funktioniert die Komponente einfach nicht.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code