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 beauftragen 😞

    App.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() );
    	}
    }
    

Anmelden zum Antworten