A callback was made on a garbage collected delegate

Post Reply
AndreasFurster
Posts: 6
Joined: Tue Feb 28, 2017 7:13 pm

A callback was made on a garbage collected delegate

Post by AndreasFurster » Tue Feb 28, 2017 7:31 pm

Hi,

We're developing a program with CameraControl.Devices. We are using Canon camera's.

When we capture with multiple camera's, the last ICameraDevice.TransferFile call causes the following error:
Managed Debugging Assistant 'CallbackOnCollectedDelegate' has detected a problem in "C:\path\to\app.exe"

Additional information: A callback was made on a garbage collected delegate of type 'Canon.Eos.Framework!Canon.Eos.Framework.Internal.SDK.Edsdk+EdsProgressCallback::Invoke'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called.
See viewtopic.php?t=332
And https://social.msdn.microsoft.com/Forum ... delegate-c

Do you have any idea where this comes from? Some things I can check?
If needed i'll post more info.

Kind regards,
Andreas F

A callback was made on a garbage collected delegate

Advertisment
 

Duka Istvan
Posts: 684
Joined: Sat Oct 03, 2015 7:57 pm

Re: A callback was made on a garbage collected delegate

Post by Duka Istvan » Tue Feb 28, 2017 10:22 pm

Do you use the latest source code ?
If i remember i get same error in dcc too, but i solved somehow, but will be hard to find how ....

AndreasFurster
Posts: 6
Joined: Tue Feb 28, 2017 7:13 pm

Re: A callback was made on a garbage collected delegate

Post by AndreasFurster » Wed Mar 01, 2017 1:43 pm

I just updated the source code. No big differences, so no fix.

I think the problem is that the Canon.Eos.Framework.Internal.EosImageTransporter.progress method/callback (attached with EdsSetProgressCallback) can't be called from the EDSDK.dll because something is GC'ed. (Probably the EosImageTransporter or CanonSDKBase?)

But we don't know how to fix this. Do you've any idea where to start looking? We have this problem for days now, and we're running on a deadline. Any help appreciated!

Duka Istvan
Posts: 684
Joined: Sat Oct 03, 2015 7:57 pm

Re: A callback was made on a garbage collected delegate

Post by Duka Istvan » Wed Mar 01, 2017 2:44 pm

Do you use transfer progress indicator in your app? If not you can comment that line

AndreasFurster
Posts: 6
Joined: Tue Feb 28, 2017 7:13 pm

Re: A callback was made on a garbage collected delegate

Post by AndreasFurster » Wed Mar 01, 2017 3:43 pm

No we don't. I just commented them.

I don't get the error anymore, but the last image is not downloaded. The file was created but the image is not downloaded (stays at 0 bytes).

Duka Istvan
Posts: 684
Joined: Sat Oct 03, 2015 7:57 pm

Re: A callback was made on a garbage collected delegate

Post by Duka Istvan » Wed Mar 01, 2017 4:10 pm

Seems the camera object is disposed before transfer, the application exit after capture ?

AndreasFurster
Posts: 6
Joined: Tue Feb 28, 2017 7:13 pm

Re: A callback was made on a garbage collected delegate

Post by AndreasFurster » Wed Mar 01, 2017 5:00 pm

The application hangs when Edsdk.EdsDownload is called. The application is not exited.

Our code:

Code: Select all

ServiceProvider.DeviceManager.PhotoCaptured += CameraDeviceManagerOnPhotoCaptured;
foreach (var position in positions)
{
    _capturedPhotos = 0;

    foreach (var device in ServiceProvider.DeviceManager.ConnectedDevices)
    {
        CapturePicture(device);
    }

    while (ServiceProvider.DeviceManager.ConnectedDevices.Any(c => c.IsBusy) || _capturedPhotos < ServiceProvider.DeviceManager.ConnectedDevices.Count)
    {
        Thread.Sleep(500);
    }
}

ServiceProvider.DeviceManager.PhotoCaptured -= CameraDeviceManagerOnPhotoCaptured;

Code: Select all

private void CapturePicture(object device)
{
    bool doRetry;

    do
    {
        doRetry = false;
        try
        {
            ((ICameraDevice) device).CapturePhoto();
        }
        catch (DeviceException exception)
        {
            if (exception.ErrorCode == ErrorCodes.MTP_Device_Busy || exception.ErrorCode == ErrorCodes.ERROR_BUSY)
            {
                Thread.Sleep(500);
                doRetry = true;
            }
            else
            {
                throw;
            }
        }
    } while (doRetry);
}

Code: Select all

private void CameraDeviceManagerOnPhotoCaptured(object sender, PhotoCapturedEventArgs eventArgs)
{
    if (eventArgs == null)
        return;

    try
    {
        var filePath = Path.Combine(Settings.Default.PhotoFolderPath, _context.Identifier);
        if (!Directory.Exists(filePath))
            Directory.CreateDirectory(filePath);

        filePath = Path.Combine(filePath, FolderName);
        if (!Directory.Exists(filePath))
            Directory.CreateDirectory(filePath);

        filePath = Path.Combine(filePath, $"{_currentPosition.Name} - {eventArgs.CameraDevice.LoadProfile().DisplayName}.jpg");

        Logger.Info($"Attempting to save the photo to \"{filePath}\"…");

        if (File.Exists(filePath))
            throw new DuplicateNameException("The name of the picture already exists");

        eventArgs.CameraDevice.TransferFile(eventArgs.Handle, filePath);
        eventArgs.CameraDevice.IsBusy = false;

        eventArgs.FileName = filePath;
        _context.PhotoPaths[_currentPosition.Id] = eventArgs;

        _capturedPhotos++;
        _captureCompleted = true;

    }
    catch (Exception e)
    {
        Logger.Error("Error while trying to process captured photo.", e);

        eventArgs.CameraDevice.IsBusy = false;
        _capturedPhotos++;
    }
}


Duka Istvan
Posts: 684
Joined: Sat Oct 03, 2015 7:57 pm

Re: A callback was made on a garbage collected delegate

Post by Duka Istvan » Wed Mar 01, 2017 7:05 pm

Try the CapturePicture(device); to run in a new thread

AndreasFurster
Posts: 6
Joined: Tue Feb 28, 2017 7:13 pm

Re: A callback was made on a garbage collected delegate

Post by AndreasFurster » Thu Mar 02, 2017 1:27 pm

Doesn't work...

As a workaround we try to capture the photo's to the SD card and read them from there. This is also not working. I will create another thread for that.

Post Reply