Я пишу программу, и каждый раз, когда я закрываю свою форму, она выдает исключение, сообщающее, что мой стек переполнен в строке, закрывающей фоновый рабочий ...
Я столкнулся с этой проблемой уже некоторое время, яЯ пытался найти решение проблемы, но я пока не нашел нужного решения ...
Мои предположения по устранению неполадок следующие:
- Изображения в картинке занимают ресурсы ине сбрасываются при отмене программы
- Фоновый рабочий все еще занят
Вот мой код, заранее спасибо!
Элементы
Picturebox называется видеобокс
Кнопка называется btnOpenCamera_Click
Кнопка называется btnCloseCamera_Click
Метка называется backgroundworkerStatus
Переменные
Global
Mat videoFrame;
VideoCapture video(0);
Личное
bool flag_cameraStatus = true;
bool flag_backgroundworkerStatus = false;
Functions
private: System :: Void MainForm_FormClosing
// this event is triggered when application is closing
video.release();
/* Exception is thrown here "System.StackOverflowException" */
backgroundWorker->CancelAsync();
if (backgroundWorker->IsBusy == false) {
checkBackgroundworkerStatus();
this->Close();
}
else {
MessageBox::Show("Backgroundworker not aborted");
e->Cancel = true;
}
private: System :: Void btnOpenCamera_Click
// this is a button for turning on camera
flag_cameraStatus = true;
backgroundWorker->RunWorkerAsync();
private: System :: Void btnCloseCamera_Click
// this is a button for turning off camera
flag_cameraStatus = false;
videoBox->Image = nullptr;
int openCamera ()
// this is a button for turning off camera
if (!video.isOpened()) {
MessageBox::Show("Cannot Find Camera!");
return -1;
}
while (flag_camera) {
video >> videoFrame;
if (videoFrame.empty()) {
break;
}
/* These lines of code converts Opencv mat to bitmap for picturebox to display */
System::Drawing::Graphics^ graphics = videoBox->CreateGraphics();
System::IntPtr ptr(videoFrame.ptr());
System::Drawing::Bitmap^ b = gcnew System::Drawing::Bitmap(videoFrame.cols, videoFrame.rows, videoFrame.step, System::Drawing::Imaging::PixelFormat::Format24bppRgb, ptr);
System::Drawing::RectangleF rect(0, 0, videoBox->Width, videoBox->Height);
graphics->DrawImage(b, rect);
/* Was wondering if I need these lines of code below */
/* delete graphics; */
if (flag_camera == false) {
videoBox->Image = nullptr;
return 0;
}
void checkBackgroundworkerStatus ()
// this function is used to check if backgroundworker is busy
// it will identify the status via the backcolor of label backgroundworkerStatus
if(backgroundWorker->IsBusy==true)
backgroundworkerStatus->BackColor = Color::Green;
else
backgroundworkerStatus->BackColor = SystemColors::Control;
private: System :: Void backgroundWorker_DoWork
// this event is triggered when background worker is working
if (backgroundWorker->CancellationPending == false) {
checkBackgroundworkerStatus();
openCamera();
}
else {
this->backgroundWorker->CancelAsync();
}
private: System :: Void backgroundWorker_RunWorkerCompleted
// this event is triggered when background worker is done working
checkBackgroundworkerStatus();
Некоторые последние заметки ...
Я установил
WorkerSupportsCancellation = true
WorkerReportsProgress = true