MAU787 Ответов: 1

Делегаты собирают мусор


всем привет
у меня есть одно приложение, которое вызывает одну функцию из dll.
эта библиотека dll вызывает один делегат для захвата отпечатка пальца.
но после 4-5 захватов я получаю ошибку..
A callback was made on a garbage collected delegate of type 'SOSComp!CG4Essentials.APIWrapper+CG4_CallbackResultImage::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.


SSO-это моя dll, а CallbackResultImage-мой делегат.
Я выпучил глаза на эту проблему и получил несколько решений
я сделал свое объявление делегата статическим и также инициализировал его при каждом вызове функции. Но все равно получаю ту же ошибку.
пожалуйста, помогите мне...
да благословит вас всех Господь..
спасибо..:)

Sergey Alexandrovich Kryukov

Обычно этого не должно происходить; если экземпляр делегата доступен, он не может быть собран в мусор. Это может означать, что вы испортили механизм делегирования каким-то действительно хитрым способом, который я сейчас не могу себе представить. Итак, можете ли вы сделать полный, но очень маленький образец кода, который можно было бы использовать для воспроизведения проблемы? Он не должен использовать никаких специальных аппаратных средств. Если это проблема, пожалуйста, покажите соответствующие фрагменты вашего кода: как вы объявляете тип делегата, экземпляр делегата, вызываете его, добавляете обработчик в список вызовов экземпляра делегата.
--СА

MAU787

да, я использую сканер отпечатков пальцев.
я объявляю делегата таким образом..
публичный статический APIWrapper.CG4_CallbackResultImage _CallbackResultImageDelegate=нуль;

затем назначение функции делегату в конструкторе класса:
публичный WrapperClass()
{

_CallbackResultImageDelegate = новый APIWrapper.CG4_CallbackResultImage(UserResultFuc);

GC.KeepAlive(_CallbackResultImageDelegate);
}


затем вызов делегата выглядит следующим образом:
СРН = APIWrapper.CG4_M_Capture_RegisterCallbackResultimage(
nHandle,
_CallbackResultImageDelegate,
этот
);

затем вызывается функция, которая вызовет этот делегат из машинного кода

Sergey Alexandrovich Kryukov

И все же этого недостаточно. И ваша первая строка не будет компилироваться. Где находится определение типа делегата? Не путайте типы делегатов и экземпляры. Почему вы используете GC.KeepAlive?
Где находится определение APIWrapper?
--СА

MAU787

у меня есть файл класса, который использует SDK устройства, и он содержит все делегаты..

MAU787

я получил это решение, но я не знаю, где находится mda.config и как его включить:
http://msdn.microsoft.com/en-us/43yky316(против.80).aspx-файл

Member 2053006

Из опубликованного кода Вы объявляете ссылку на делегат статической, поэтому вы можете ссылаться только на один делегат, но создаете экземпляр делегата для каждого экземпляра WrapperClass.

Если вы создадите более одного WrapperClass, то один из экземпляров делегата выйдет за пределы области действия и вызовет эту ошибку.

Либо удалите статику в первой строке, чтобы иметь ссылку на делегат для каждого WrapperClass, либо создайте один экземпляр делегата в статическом конструкторе WapperClass (функция обратного вызова-UserResultFuc - должна быть передана экземпляру WrapperClass в качестве параметра)

Еще одна вещь, которую следует помнить, - это то, что вам нужно будет удалить делегат, когда вы закончите с экземпляром WrapperClass. Метод dispose, вероятно, был бы лучшим способом сделать это.

MAU787

спасибо большое...:)

MAU787

Привет я изменил свой код в соответствии с инструкцией ur
объявленный делегат как это:
общественные APIWrapper.CG4_CallbackResultImage _CallbackResultImageDelegate = нуль;


затем назначение функции делегату в конструкторе класса:
публичный WrapperClass()
{

_CallbackResultImageDelegate = новый APIWrapper.CG4_CallbackResultImage(UserResultFuc);


}


затем вызов делегата выглядит следующим образом:

WrapperClass wrp = новый WrapperClass();
СРН = APIWrapper.CG4_M_Capture_RegisterCallbackResultimage(
nHandle,
_CallbackResultImageDelegate,
РРП
);
и после обработки я устанавливаю делегат как null
он запускается в первый раз, а затем выдает ошибку...

1 Ответов

Рейтинг:
2

Dave Kreskowiak

Я сомневаюсь, что это все еще будет полезно для операции, потому что он задал этот вопрос восемь лет назад.

martonthenagy

Правда. Может быть, кому-то еще это пригодится. Как я нашел связанный ответ сегодня, который был полезен, несмотря на то, что ему тоже 8 лет.