Search code examples
c++backgroundworker

Send int array via backgroundworker ReportProgress in c++


I'm trying to send an int array from by backgroundworker thread to my main thread by using ReportProgress() method.

Now if I tried to send an integer or a string, it worked ok. but If I try to use an int array it does not seem to work.

How do I solve this problem?

private: System::Void backgroundWorker1_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e) {
    //...do work..
    int foo[5] = { 16, 2, 77, 40, 12071 };
    backgroundWorker1->ReportProgress(99, foo);
}

Solution

  • cannot convert argument 2 from 'int *' to 'System::Object ^

    C++/CLI allows you to use unmanaged types, like int foo[5]. But they are not convertible to System::Object, the argument type of ReportProgress(). You must use a managed array here. Fix:

     array<int>^ foo = gcnew array<int> { 16, 2, 77, 40, 12071 };
     backgroundWorker1->ReportProgress(99, foo);
    

    Your ProgressChanged event handler then needs to cast the Object back to the array:

     array<int>^ foo = safe_cast<array<int>^>(e->UserState);
    

    Noteworthy perhaps is that your original int foo[5] is in fact convertible to IntPtr with a cast which then can be boxed in Object. But in the specific case of ReportProgress() that will turn out very poorly, the variable is long gone by the time that the ProgressChanged event will start running. ReportProgress doesn't wait for the event handler to complete, under the hood it uses Control::BeginInvoke() instead of Invoke(). Using a managed array that's stored on the heap ensures that this can't go wrong and the array stays valid. The garbage collector then ensures that the array is released when it is no longer used.