2 Backgroundworker und Delegates?
-
Hallo zusammen,
ich bin neu hier und auch neu im Thema C++ mit .Net.
Ich suche Hilfe nach dem ich keine passende Antwort für meine Fragen bekommen habe.ich habe folgendes Problem.
Ich habe eine WinForm-Anwendung mit einem Backgroundworker-Thread für einen Progressbar mit dem ich schön meinen Progress per Delegate visualisiseren kann. Nun möchte ich aber aus nem zweiten Backgroundworker-Thread in einer separaten Klasse (Zip) den Progressbar der ersten Klasse (App) nutzen und das eben mit zwei Threads, einen für Zip und einen für App.Kann mit bitte jemand dabei nen Tipp geben wie ich das anstellen kann, ich komme einfach nicht mehr weiter?
Gruß Joe
-
Zeig doch mal dein Versuch oder mindestens ein wenig Code, welcher dein Problem zeigt.
-
theta schrieb:
Zeig doch mal dein Versuch oder mindestens ein wenig Code, welcher dein Problem zeigt.
Hallo Theta,
anbei meine Zip.h/cpp-Files mit der darin enthaltenen Decompress-Klasse, ich hoffe das hilft dir ein wenig?
Die UpdateProgress-Funktion reportet bisher den progress in dem sie auf die Konsole schreibt, nun weiß ich eben nicht wie ich eine Delegate-Fkt implementieren muss um überhaupt rauszukommen und die App-Klasse aufzurufen um dann wieder den Progress zu beauftragenApp.cpp
private: delegate void InvokeDelegate(int value); private: void InvokeProgressPerformStep(int value) { if(progressBar1->InvokeRequired) { progressBar1->Invoke(gcnew InvokeDelegate(this, &Form1::PerformProgressStep),value); } else { Form1::SetProgressValue(value); } } private: void SetProgressValue(int value) { this->progressBar1->Value = value; } private: void PerformProgressStep(int value) { if(this->progressBar1->Value >= this->progressBar1->Maximum) { this->progressBar1->Step = -1 * value; } else if(this->progressBar1->Value <= 1) { this->progressBar1->Step = value; } this->progressBar1->PerformStep(); }
Zip.h
using namespace System; using namespace System::IO; using namespace System::IO::Compression; using namespace System::ComponentModel; public ref class Decompress { //public: delegate public: Decompress(String^ filenameIn,String^ filenameOut ); protected: ~Decompress(void); private: System::ComponentModel::BackgroundWorker^ WorkerThread; private: void InitializeBackgoundWorker(String^ filenameIn,String^ filenameOut ); private: void Worker(Object^ sender, DoWorkEventArgs^ e); public: void GZipCompressDecompress(BackgroundWorker^ worker, String^ filenameIn,String^ filenameOut ); //public: delegate void InvokeDelegate(int value); public: virtual void UpdateProgress(Object^ sender, ProgressChangedEventArgs ^e); };
Zip.cpp
#include "stdafx.h" #include "zip.h" #using <System.dll> // delegates using namespace System; using namespace System::IO; using namespace System::IO::Compression; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; using namespace System::Runtime::InteropServices; // needed to call external application using namespace System::Threading; ref class decompressFiles { public: String^ fileIn; String^ fileOut; decompressFiles(String^ in, String^ out) { //Console::WriteLine("constructed {0} {1}.\n",in,out); fileIn = in; fileOut = out; //fileIn = gcnew String(in); //fileOut = gcnew String(out); //Console::WriteLine("constructed {0} {1}.\n",fileIn,fileOut); } protected: ~decompressFiles(void) { Console::WriteLine("destructed {0} {1}.\n",fileIn,fileOut); } }; Decompress::Decompress(String^ filenameIn,String^ filenameOut ) { InitializeBackgoundWorker(filenameIn,filenameOut); Console::WriteLine("Decompress constructed.\n"); } Decompress::~Decompress(void) { Console::WriteLine("Decompress descructed.\n"); } void Decompress::UpdateProgress(Object^ sender, ProgressChangedEventArgs ^e) { Console::WriteLine("Decompress::UpdateProgress event={0}\n",e->ProgressPercentage); } void Decompress::InitializeBackgoundWorker(String^ filenameIn,String^ filenameOut) { this->WorkerThread = gcnew System::ComponentModel::BackgroundWorker; // // WorkerThread // this->WorkerThread->WorkerReportsProgress = true; this->WorkerThread->WorkerSupportsCancellation = true; WorkerThread->DoWork += gcnew DoWorkEventHandler( this, &Decompress::Worker ); //WorkerThread->RunWorkerCompleted += gcnew RunWorkerCompletedEventHandler( this, &ActrosInstall::Form1::UpdateProgressBarCompleteted); this->WorkerThread->ProgressChanged += gcnew ProgressChangedEventHandler(this, &Decompress::UpdateProgress ); Console::WriteLine("Decompress::Backgroundworker created.\n"); decompressFiles^ dcFiles1 = gcnew decompressFiles(filenameIn,filenameOut); Console::WriteLine("dcFiles1 {0} {1}.\n",dcFiles1->fileIn,dcFiles1->fileOut); WorkerThread->RunWorkerAsync(dcFiles1); Console::WriteLine("Decompress::Backgroundworker started.\n"); } void Decompress::Worker(Object^ sender, DoWorkEventArgs^ e) { // Get the filenames of argument. // Get the BackgroundWorker that raised this event. BackgroundWorker^ worker = dynamic_cast<BackgroundWorker^>(sender); decompressFiles^ dc = safe_cast<decompressFiles^>(e->Argument); Console::WriteLine("start decompress: from {0} to {1}\n",dc->fileIn, dc->fileOut); GZipCompressDecompress(worker,dc->fileIn, dc->fileOut); Console::WriteLine("decompress finished.\n"); } void Decompress::GZipCompressDecompress(BackgroundWorker^ worker, String^ filenameIn, String^ filenameOut ) { String^ dstFile = ".\\decompressed-file.bin"; FileStream^ fsIn; // will open and read the srcFile FileStream^ fsOut; // will be used by the GZipStream for output to the dstFile GZipStream^ gzip; const int bufferSize = 0x280000; array<Byte>^buffer = gcnew array<Byte>(bufferSize); int count = 0; try { fsIn = gcnew FileStream(filenameIn, FileMode::Open,FileAccess::Read,FileShare::Read); fsOut = gcnew FileStream(filenameOut, FileMode::OpenOrCreate,FileAccess::Write,FileShare::None); gzip = gcnew GZipStream(fsIn, CompressionMode::Decompress, true); while (true) { count = gzip->Read(buffer, 0, bufferSize); Console::WriteLine( "read: {0}.",count); if (count != 0) { fsOut->Write(buffer, 0, count); worker->ReportProgress(0); Console::WriteLine( "written: {0}.",count); } if (count != bufferSize) { worker->ReportProgress(1); // have reached the end break; } } } catch (Exception^ ex) { // handle or display the error //System.Diagnostics.Debug.Assert(false, ex.ToString()); worker->ReportProgress(2); Console::WriteLine( "Error: {0}.",ex->ToString() ); } }