Backgroundworker und Label
-
Hallo Zusammen,
Ich bins wieder Hatte hier im Forum schonmal was geschrieben und es wurde mir eigentlich gleich geholfen, danke nochmals für die Hilfe. Nun habe ich wieder ein Problem, ich habe in meinem Programm mehrere Klassen und habe bei einer Klasse noch einen Backgroundworker hinzugefügt. Dort ist auch ein Befehl drin, wo auf dem GUI ein Label ist, welches immer den aktuell durchsuchten Computer anzeigen sollte. Nun habe ich das Problem das der Label nichts anzeigt wenn ich das Programm ausführe, ich denke das liegt daran, weil in dieser Zeit der Backgroundworker arbeitet und somit nichts auf dem Label geschrieben werden kann.
Meine Frage wäre jetzt wie ich dieses Problem lösen könnte, ich habe vom Befehl label->invoke schon gehört und probiert, weiss jedoch nicht ob das der richtige Ansatz wäre...
Für jeden Hinweis wäre ich dankbarMFG
redhwaks// LogCom.cpp : main project file. #include "stdafx.h" #include "Form1.h" #include "csAD_Getuser.h" #include "csAD_Getcomputer.h" #include "csAD_Username.h" using namespace LogCom; [STAThreadAttribute] int main(array<System::String ^> ^args) { // Enabling Windows XP visual effects before any controls are created Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); // Create the main window and run it Application::Run(gcnew Form1()); return 0; } // Instanzierung Button Get User System::Void Form1::btShowUser_Click(System::Object^ sender, System::EventArgs^ e) { ArrayList^ UserList =gcnew ArrayList; csAD_Getuser::getuser(UserList); Form1::lbListUser->Items->Clear(); Form1::lbListUser->Items->AddRange(UserList->ToArray()); Form1::lbListComputer->Items->Clear(); // Anzahl User wird ermittelt und ausgegeben. int^ anzahl = Form1::lbListUser->Items->Count; Form1::lbUserFound->Text =anzahl+" Users found"; } // Instanzierung Klasse csAD_Getcomputer System::Void Form1::btShowComputer_Click(System::Object^ sender, System::EventArgs^ e) { Form1::lbListComputer->Items->Clear(); // Instanzierung Methode um Computer vom AD zu holen csAD_Getcomputer::getcomputer(ComputerList); // Instanzierung der Methode um PC anzupingen und Daten holen Form1::backgroundWorker_getping->RunWorkerAsync(); } // Instanzierung der Klasse csAD_Username System::Void Form1::lbListUser_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e) { String^ selectedUser; // Filter für ausgewählten User wird gesetzt selectedUser = Form1::lbListUser->SelectedItem->ToString(); // Instanzierung der Methode um Filter für Loginnamen su setzen csAD_Username::username(selectedUser); } // Inszanzierung BackgroundWorker getping System::Void Form1::backgroundWorker_getping_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) { csAD_Getcomputer::getping(form, ComputerList,cn,selectedUser); } System::Void Form1::backgroundWorker_getping_RunWorkerCompleted(System::Object ^sender, System::ComponentModel::RunWorkerCompletedEventArgs ^e){ int^ onlinecomputer = ComputerList->Count; Form1::lbInistitutePC->Text = "Total "+onlinecomputer+" Institute Computer registered"; Form1::lbInistitutePC->Update(); // Schreibt gefundene Computer Win7 in LB Form1::lbListComputer->Items->AddRange(form->ToArray()); //Computer wird ermittelt und ausgegeben Form1::lbListComputer->Update(); int^ anzahlComputer = Form1::lbListComputer->Items->Count; Form1::lbComputerFound->Text =anzahlComputer+" Computer are used"; Form1::lbComputerFound->Update(); // Zeigt immer den aktuell durchsuchten Computer an. Form1::lbsearch->Text = cn; Form1::lbsearch->Update(); }
Form1::lbsearch->Text = cn;
Form1::lbsearch->Update();
Diese Labels sollten den Befehl ausführen.
-
Ja, Invoke bzw. BeginInvoke ist der richtige Ansatz.
-
Hmmmm, Wie funktioniert so ein Invoke ganz genau? Laut MSDNAA Beispiel welches ich gefunden habe, wird mit der Invoke Funktion auf eine Methode delegatet. Ich will ja aber eigentlich nur einen Wert welches ich in einer Variable habe, auf der GUI in einem Label zeigen...
So trivial kann es wahrscheinlich nicht sein oder?
Form1::lbsearch->Invoke(cn);
-
Ich will ja aber eigentlich nur einen Wert welches ich in einer Variable habe, auf der GUI in einem Label zeigen...
Schön - und das musst Du auf dem GUI Thread machen, was Du mit Invoke erreichen kannst.
-
Die wichtige Frage wäre eigentlich: was genau macht 'csAD_Getcomputer::getping(...)'?
Wenn diese alle Computer der Liste 'anpingt', so wird das Ereignis 'RunWorkerCompleted' natürlich erst am Ende einmalig aufgerufen!!!
-
Hi Th69,
Genau bei der Methode "csAD_Getcomputer::getping(...)" werden alle Computer der Liste angepingt. Hmmmm das Ereignis RunWorkerCompleted wir ja nur einmalig aufgerufen wie du sagst, müsste man damit im Label was angezeigt wird, quasi jeden Computer einzeln anpingen und dann immer den nächsten wieder nehmen, das würde aber dann auch bedeuten dass man mehrere Backgroundworker machen müsste? Das wäre glaub ich Programmier Technisch gesehen eher nicht gut, dann müsste ich für die ca. 170 Computer welche wir haben, einen einzelen Backgroundworker machen...
Kein Plan wie ich das bewerkstelligen soll...
Hat jemand ein CodeBeispiel oder so wie man das machen könnte, Invoke zu implementieren hab ich auch nicht geschafftps: Sorry das ich so spät Antwort geschrieben habe
-
Hi,
kannst du denn den Code von 'csAD_Getcomputer::getping()' verändern?
Dann solltest du dort ein Event definieren und je Computer-Ping werfen.
Und im Backgroundworker abonnierst du dann dieses Event und leitest dann die Daten per (Begin)Invoke() an den GUI-Thread weiter.
Ein Beispiel zu Invoke() gibt es in der MSDN: http://msdn.microsoft.com/de-de/library/a1hetckb(v=vs.80).aspx
-
Hi Zusammen,
Ich kann auch den Code vom 'csAD_Getcomputer::getping()' ändern, dann versuche ich es mal mit der Methode die beschrieben hast, ich melde mich dann wieder falls es geklappt hat oder nicht weiterkomme
-
Hallo Zusammen,
Bin mit dem Invoke Zeug etc. leider nicht weitergekommen, nun habe ich gelesen dass man auch bei einem Backgroundworker, ProgressChanged aufrufen kann und damit dann die Labels in der GUI ändern kann.
Ich hab nun unter dem Aufruf;
System::Void Form1::btShowComputer_Click(System::Object^ sender, System::EventArgs^ e)
Noch diesen Code hinzugefügt:
Form1::backgroundWorker_getping->ReportProgress(cn);
In der ProgressChanged Methode kommen dann die Befehle um die Labels zu verändern:
System::Void Form1::backgroundWorker_getping_ProgressChanged(System::Object^ sender, System::ComponentModel::ProgressChangedEventArgs^ e) { Form1::lbsearch->Text = cn; Form1::lbsearch->Update(); }
Leider bekomme ich beim kompilieren dann die Fehlermeldung:
Error 1 error C2664: 'void System::ComponentModel::BackgroundWorker::ReportProgress(int)' : cannot convert parameter 1 from 'System::String ^' to 'int'Normalerweise ist ja beim ReportProgress immer die Angaben zur ProgressBar vorhanden kann ich hier nicht einfach die String Variable mit dem Computernamen weitergeben die angezeigt werden soll?
Danke für eure Hilfe im Voraus