Cześć
Próbuje swoich sił w programowani wielowątkowych, jako że background worker nie bardzo odpowiada mi moim potrzebom postanowiłem zostać przy Task^.
Jednak pojawia się problem w jaki sposób go anulować, dokumentacja MSDN pokazuje jak to zrobić z tak zwanym CancellationToken, no ale niestety nie mogę sobie poradzić.
MyForm.h
#pragma once
namespace Task_Factory {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Threading::Tasks;
using namespace System::Threading;
public ref class MyForm : public System::Windows::Forms::Form
{
public:
MyForm(void);
Task^ taskFact;
void DoSomeWork(CancellationToken t);
void updateProgress(int i);
protected:
~MyForm();
private:
delegate void updateUIdelegate(int i);
void updateUI(int i);
System::ComponentModel::Container ^components;
void button1_Click(System::Object^ sender, System::EventArgs^ e);
void button2_Click(System::Object^ sender, System::EventArgs^ e);
System::Windows::Forms::Button^ btnStart;
System::Windows::Forms::Button^ btnStop;
System::Windows::Forms::ProgressBar^ progressBar1;
System::Windows::Forms::Label^ label1;
CancellationTokenSource^ source;
#pragma region Windows Form Designer generated code
void InitializeComponent(void);
#pragma endregion
};
}
MyForm.Cpp
#pragma once
#include "MyForm.h"
namespace Task_Factory {
MyForm::MyForm(void) {
InitializeComponent();
this->source= gcnew CancellationTokenSource();
}
void MyForm::DoSomeWork() {
Progress<int>^ progressHandler = gcnew Progress<int>(gcnew Action<int>(this, &MyForm::updateProgress));
IProgress<int>^ progress = safe_cast<IProgress<int>^>(progressHandler);
for (size_t i = 0; i < 100; i++)
{
progress->Report(i);
System::Threading::Thread::Sleep(1000);
}
}
void MyForm::updateProgress(int i) {
updateUIdelegate^ UIaction = gcnew updateUIdelegate(this, &MyForm::updateUI);
this->BeginInvoke(UIaction, i);
}
void MyForm::updateUI(int i) {
this->label1->Text = i+"%";
this->progressBar1->Value = i;
}
void MyForm::button1_Click(System::Object^ sender, System::EventArgs^ e) {
this->taskFact = Task::Factory->StartNew(gcnew Action(this, &MyForm::DoSomeWork), this->source->Token);
}
void MyForm::button2_Click(System::Object^ sender, System::EventArgs^ e) {
this->source->Cancel();
}
MyForm::~MyForm() {
if (components) {
delete components;
}
}
void MyForm::InitializeComponent(void) {
(...)
}
}
W momencie wciśnięcia klawisza start(button1) rozpoczyna się nowy wątek, wypełniający pasek postępu, w tym momencie możliwe jest poruszanie okienkiem, bez zadnych zwiek itp,
W momencie wciśnięcia Stop Token powinnien wyzwolić sygnał Cancel(),
Próbowałem wielu rzeczy jeżeli linie
this->source->Cancel();
wkleje do funkcji obsługi zdarzenie klawisza start:
this->taskFact = Task::Factory->StartNew(gcnew Action(this, &MyForm::DoSomeWork), this->source->Token);
this->source->Cancel();
to wątek się nie rozpoczyna.
Chciałbym poprawnie skonfigurować obsługę zdarzenia dla klawisza STOP, w taki sposób aby wątek był przerwany w momencie jego wciśnięcia.
Pozdrawiam