Share via


A callback was made on a garbage collected delegate of type

Question

Sunday, October 18, 2009 7:23 AM

Hello All,

I have my own dll in which we capture data from external usb device. In my application we have a picturebox when user clicks on this it capture the data from device. It works fine for first time means when we click image first time application succesfully captures data from device  but when we click second time it throws following error "A callback was made on a garbage collected delegate of type ....". Please tell me what may be the reason I have attched the source code as well... 

using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MyCompany.MyAPIDLL;

namespace Test_APP
{   

    public partial class Form1 : Form
    {
        protected  MyApi mpi;
        delegate void AddMessageDelegate(string message);
        private int age;
        private char ____;
      

        public void MPIHandler(int type, String Data)
        {
            switch (EventType)
            {
                case MyApi.DATA_CAPTURED:
                   
                        laber4.text = Data.toString
                       
                        AddMessageString("1");
                   
                    break;

                case MyApi.DATA_CARUPTED:
                    {
                        MessageBox.Show("Data is corrupted!!");
                     
                    }
                    break;
                

            }

        }
        
       
        public Form1()
        {
            InitializeComponent();
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            mpi = new MyApi();
            mpi.RegApp(MPIHandler);
    }


      

        private void pictureBox3_MouseClicked(object sender, System.Windows.Forms.MouseEventArgs e)
        {

            
                    pictureBox3.Visible = false;
                    pictureBox4.Visible = true;
                    mpi.captureData();
             

        }


        public void AddMessageString(String resultType)
        {

            if (this.InvokeRequired)
            {
                this.Invoke(new AddMessageDelegate(AddMessageString), resultType);
            }
            else
            {
               
                label6.Visible = true;
                button3.Visible = true;
                button4.Visible = true;
            }
        }
       
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            mpi.UnRegApp();
        }

      
        

       
       
       
    }
}

All replies (7)

Sunday, October 18, 2009 7:59 AM âś…Answered | 1 vote

The problem isn't in your code, although you could probably fix it.  What matters is what happens to the delegate instance that you pass to mpi.RegApp().  In all likelihood, that API forgets to store a reference to the delegate you pass and passes it straight on to some unmanaged code.  When the garbage collector runs, it doesn't see a reference to the delegate object (it can't see references held my unmanaged code) and collects the object.  The next time the unmanaged code makes the callback, it goes kaboom.

You should contact the provider of "MyAPIDLL" and ask for a fix.  This code may provide a workaround for the bug:

protected MyApi mpi;
private DelegateTypeWhosNameIDontKnow callback;
//etc..

private void Form1_Load(object sender, EventArgs e) {
  mpi = new MyApi();
  callback = new DelegateTypeWhosNameIDontKnow(MPIHandler);
  mpi.RegApp(callback);
}

The callback field ensures that the delegate object stays referenced.Hans Passant.


Sunday, October 18, 2009 8:03 AM

Hi,

The only thing I can think of is that the mpi object is releasing the reference to the delegate you passed, or it is only keeping a weak reference and not a strong one.

If you call

mpi.RegApp(MPIHandler);

in the bottom of the MPIHandler method, does the problem still occur ? It may be the MPI object releases the delegate reference after each callback for some reason, and that re-registering will fix it. That's just a guess though.


Sunday, October 18, 2009 9:30 AM

Hello I have updated my code,But still I am facing the same problem ..... :(.... I have made these updations 

protected Myapi myapi; 

private MyApi.EventHandler theCallback; 

.... 

private void Form1_Load(object sender, EventArgs e) 

mpi = new MyApi(); 

theCallback = new MyApi.EventHandler(MPIHandler); 

mpi.RegApp(theCallback); 

} ........

Please Suggest.... Prateek


Sunday, October 18, 2009 1:24 PM | 1 vote

Well, too bad, it was worth a shot.  Now you need to talk the owner of MyApi.  Show him this thread so he'll know what to do.
Hans Passant.


Sunday, October 18, 2009 6:55 PM

Hi,

Nobugz is probably correct, you need to get the developer of the MyApi object to fix their code. However, if the problem really only occurs after the second callback, you may be able to fix the problem by re-registering the callback delegate inside the callback itself, like I suggested originally. Have you tried that ?


Sunday, October 18, 2009 7:36 PM

Nah, can't work.  He doesn't know when the callback will take place.
Hans Passant.


Sunday, October 18, 2009 8:13 PM

He knows when the callback is in progress though... it's his method being called. It depends on what the bug is inside the 3rd party object. If it's just not keeping a (strong) reference at all, then he's got a problem... but if the 3rd party code is releasing it's strong reference after each callback is made, then re-registering a new delegate (or the same one again if he's kept his own reference) should put a new strong reference back in the 3rd party code so the next callback works, and so on. Hard to know whether that will help without knowing what that object does, but while it's a long shot I'd say it's worth a try.