CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 40

Threaded View

  1. #20
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: How to UseWaitCursor correctly

    Quote Originally Posted by Alex F View Post
    How progress information is sent to the main thread?
    Like that:

    Code:
    System::Void Form1::DoCountWorker(FileStream ^fsInfile,BackgroundWorker ^bw,DoWorkEventArgs ^e)
    {
      BinaryReader brInfile(fsInfile);
      const int nBufferSize=512;
      array<Byte> ^abBuffer;
      int nPercent=0,nLastPercent=-1;
    
      do {
        abBuffer=brInfile.ReadBytes(nBufferSize);
        for (int i=0;i<abBuffer->Length;++i)
          ++aulCounts[abBuffer[i]];
        if ((nPercent=(100*fsInfile->Position)/fsInfile->Length)!=nLastPercent) {
          bw->ReportProgress(nPercent);
          nLastPercent=nPercent;
        }
      } while (!bw->CancellationPending && abBuffer->Length==nBufferSize);
      brInfile.Close();
      if (bw->CancellationPending) e->Cancel=true;
    }
    
    System::Void Form1::bwDoCount_ProgressChanged(System::Object^  sender, System::ComponentModel::ProgressChangedEventArgs^  e)
    {
      progress->Text=String::Format("Processing file... {0}&#37;",e->ProgressPercentage);
      progress->progressBar1->Value=e->ProgressPercentage;
    }
    Where progress is the progress dialog form object.

    By debugging I found out that the bwDoCount_ProgressChanged() event handler runs in the context of the GUI thread, so IMO inter-thread communication is done internally by BackgroundWorker.

    But the progress display doesn't cause the deadlock anyway, the problem was only exposed when I clicked the Cancel button. Cancellation is handled by this simple event handler in the progress dialog's form class:

    Code:
    System::Void Progress::bnCancel_Click(System::Object^  sender, System::EventArgs^  e)
    {
      bwParentWorker->CancelAsync();
    }
    Where bwParentWorker is a tracking handle to the BackgroundWorker object that gets passed (i.e. assigned) from the main form object to the progress dialog's form object.

    Closing the progress dialog in case I did not click the cancel button is donne by the completion handler (and works):

    Code:
    System::Void Form1::bwDoCount_RunWorkerCompleted(System::Object^  sender, System::ComponentModel::RunWorkerCompletedEventArgs^  e)
    {
      if (e->Error) MessageBox::Show(this,e->Error->Message,"Error during file processing",MessageBoxButtons::OK,MessageBoxIcon::Error);
      bCountCancelled=e->Cancelled;
      if (progress->Visible) progress->Close();  // Progress dialog is still open: close it
      Cursor->Current=csrSaved;  // This has just been added in response to Arjay's latest post
      ewhWorkerReallyFinished->Set();
    }
    But, as described above, this handler doesn't even get called when I click Cancel.
    Last edited by Eri523; September 19th, 2010 at 07:04 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured