Невозможно адаптировать процент выполнения BackgroundWorker к реальному проценту задачи

Я написал программу, которая читает короткое видео, а затем записывает пару сотен кадров с уменьшенным FPS. Это работало нормально, но цикл if блокировал пользовательский интерфейс. Я попытался создать backgroudWorker для обработки цикла «если», в то время как значения пользовательского интерфейса могли отображаться, и процесс мог быть прерван кнопкой «Отмена».
Моя проблема заключается в следующем: я не могу сделать так, чтобы цикл if прошел через все кадры:

for (i = 0; i < frames_number; i++)

до последнего кадра! он останавливается на 100, хотя я пробовал несколько решений, чтобы преобразовать прогресс «я» в процентах, как:

progress = System::Convert::ToInt32((100*(i / frames_number)));

или же

progress = (int)((float)i / (float)frames_number *100);

Вот важные фрагменты кода:

private: System::Void CreateSlowMo_Click(System::Object^  sender, System::EventArgs^  e) {
VideoCapture inputVideo(videoToOpenNameStr);
if (!inputVideo.isOpened()) {
MessageBox::Show(L"Error");
}
fps =   int(inputVideo.get(CAP_PROP_FPS)); // get the frame rate of the video
frames_number = int(inputVideo.get(CAP_PROP_FRAME_COUNT));     // get the total frames in the video
this->progressBar1->Maximum = frames_number;      // Initilize the progress bar's maximum to the number of frames
outputVideo.open(name, CV_FOURCC('M', 'J', 'P', 'G'), fps_wanted, resolution, true);  // Create an output video
if (outputVideo.isOpened())
{
this->backgroundWorker1->RunWorkerAsync(progress);     // Delegating the blocking operations to the background worker
}
else {
MessageBox::Show(L"Error creating the video");
CreateSlowMo_button->Enabled = true;
}
}

backgroundWorker1_DoWork:

private: System::Void backgroundWorker1_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e) {

progress = (int)e->Argument; // get the intial value of the argument
for (i = 0; i < frames_number; i++)
{
inputVideo >> source; // read frame

if (backgroundWorker1->CancellationPending) {   // check if the User clicked on "Cancel"e->Cancel = true;
break;    // Stop the convertion
}
if (source.empty()) { // we reached the last frame
break;
//  CreateSlowMo_button->Enabled = true;
}
if (progress > 100)
{ // verify we didn't exceed 100% of the task
backgroundWorker1->ReportProgress(100);
break;
}
outputVideo << source; // write the frame to the output video
progress = (int)(((float)i / (float)frames_number)* 100);
backgroundWorker1->ReportProgress(progress);
}
this->backgroundWorker1->ReportProgress(100);
e->Result = progress;
}

backgroundWorker1_ProgressChanged:

private: System::Void backgroundWorker1_ProgressChanged(System::Object^  sender, System::ComponentModel::ProgressChangedEventArgs^  e) {
this->progressBar1->Value = e->ProgressPercentage;
toolStripStatusLabel1->Text = "Processing..." + progressBar1->Value.ToString() + "%";
richTextBox6->Text = e->ProgressPercentage.ToString();
}

backgroundWorker1_RunWorkerCompleted:

private: System::Void backgroundWorker1_RunWorkerCompleted(System::Object^  sender, System::ComponentModel::RunWorkerCompletedEventArgs^  e) {
// in case the background process is finished with a cancel
if (e->Cancelled)
{
toolStripStatusLabel1->Text = "Task Cancelled";
}
// check if an error occurred in the backgroud process
else if (e->Error != nullptr)
{
toolStripStatusLabel1->Text = "Error while creating the SlowMo";
}
else
{   // task completed normally
this->toolStripStatusLabel1->Text = "SlowMo Created successfully!";
this->cancel_button->Enabled = false;
MessageBox::Show(L"Finished creating the sloMo");
this->toolStripStatusLabel1->Text = "Done";
this->CreateSlowMo_button->Enabled = true;
this->richTextBox5->Text = "value " + e->Result;
}
}

Вот несколько скриншотов из результатов (я добавил текстовые поля для визуализации значений ‘i’, ‘progress’ и e-> result) ‘i’ и ‘progress’ имеют тип int = 0, определенный в файлах ‘variables.h’

extern int i ;
extern int progress;

и ‘variables.cpp’:

int i = 0;
int progress =0;

Пользовательский интерфейс, когда backgroundWorker сделано

Пользовательский интерфейс, когда backgroundWorker сделано

0

Решение

Вы проверили значение frames_number? Или если любой из ваших if заявления в рамках for цикл становится истинным в любое время во время выполнения?

Я подозреваю frames_number получает неправильное значение до for петля или source.empty() становится правдой.

0

Другие решения