WinForm Control BeginInvoke/Invoke Issue

孤者浪人 提交于 2019-12-11 17:53:38

问题


I am trying to write a multithreaded WinForm in C++/CLI app using VS2012.

I know that only the UI thread can update a control and I have been using delegates and the invoke methods. However, I have run into a memory access issue when using BeginInvoke that I do not see when using Invoke.

Delegate Function:

public: delegate void pictureboxShowDelegate(int tChannelNumber,System::Windows::Forms::PictureBox^,System::Drawing::Bitmap^ colorImage);

Called Function:

void DrawCVImageShow(int tChannelNumber, System::Windows::Forms::PictureBox^ PBox, System::Drawing::Bitmap^ b)
{
    if(PBox->InvokeRequired)
    {
        pictureboxShowDelegate^ d = gcnew pictureboxShowDelegate(this,&MyForm::DrawCVImageShow);
        PBox->Invoke(d,tChannelNumber,PBox,b);
    }
    else
    {
        System::Drawing::Graphics^ graphics = PBox->CreateGraphics();
        System::Drawing::RectangleF rect(0,0,(float)PBox->Width,(float)PBox->Height);
    graphics->DrawImage(b,rect);
    }
}

If called this way, it works with no problem. If I substitute BeginInvoke for Invoke, I get an AccessViolationException. Clearly, this has to do with the garbage collection of the parameters but I simply can't figure this one out.

Any help greatly appreciated.

Thanks


回答1:


It sounds to me like whatever is calling DrawCVImageShow in the first place is Disposing the bitmap immediately after DrawCVImageShow returns.

If that's the case, there are a couple possiblities:

  • Make it so that DrawCVImageShow is the one responsible for Disposing the bitmap, not whatever calls DrawCVImageShow. (Simple solution, though probably not the best from an engineering solution: The thing that created the bitmap should generally be responsible for disposing it, and it makes DrawCVImageShow a less general method.)
  • Make a Clone of the bitmap, and dispose that one after it's been used. This is the more proper solution, in my opinion, but it does make things a little bit more complicated. You now need two versions of DrawCVImageShow, one that disposes the bitmap (for BeginInvoking), and one that doesn't (the method you have now). This also means you'll have two copies of the bitmap in memory when a BeginInvoke is needed; hopefully these bitmaps are not so large that this is an issue.


来源:https://stackoverflow.com/questions/20924641/winform-control-begininvoke-invoke-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!