WinForm控件BeginInvoke/调用问题 [英] WinForm Control BeginInvoke/Invoke Issue

查看:886
本文介绍了WinForm控件BeginInvoke/调用问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用VS2012在C ++/CLI应用程序中编写多线程WinForm.

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

我知道只有UI线程可以更新控件,并且我一直在使用委托和invoke方法.但是,在使用BeginInvoke时遇到了内存访问问题,而在使用Invoke时却看不到.

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.

代理功能:

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

被调用函数:

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);
    }
}

如果以这种方式调用,则不会有任何问题. 如果我用BeginInvoke代替Invoke,则会得到一个AccessViolationException. 显然,这与参数的垃圾收集有关,但我根本无法弄清楚这一点.

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.

谢谢

推荐答案

在我看来,首先调用DrawCVImageShow的是

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.

这篇关于WinForm控件BeginInvoke/调用问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆