Author Topic: CallbackOnCollectedDelegate - C# SYNCPROC  (Read 2214 times)

Gildarts

  • Guest
Hi i am getting Bass.Net!Un4seen.Bass.SYNCPROC::Invoke - CallbackOnCollected Delegate error on VS 2012.

Code: [Select]
public class Player
    {
        private IPlayStream stream;
        private event Action needOtherAudioSource;

        public void ChangeSong(IAudioSource Song)
        {
            if (stream != null)
            {
                stream.DontNeedThisStreamAnymore();
                changeSongHelper(Song);
            }
            else
            {
                changeSongHelper(Song);
            }
           
        }

        public void SubscribeNeedAudioSource(Action subscriberAction)
        {
            needOtherAudioSource = subscriberAction;
        }

        public void UnsubscribeNeedAudioSource(Action subscriberAction)
        {
            needOtherAudioSource -= subscriberAction;
        }

        private void changeSongHelper(IAudioSource Song)
        {
            stream = Song.CreateIPlayStream();
            stream.NotifyEndOfStream += needOtherAudioSource;
            this.Play();
        }
   // rest is not important here
    }

Code: [Select]
public class BassHddStream : IPlayStream
    {
        private int stream;
        private event Action NotifyEndOfStream;
        private SYNCPROC callback;
        private int syncID;

        public BassHddStream(String filepath)
        {
            callback = new SYNCPROC(mySync);
            stream = Bass.BASS_StreamCreateFile(filepath, 0, 0, BASSFlag.BASS_MUSIC_FLOAT | BASSFlag.BASS_SAMPLE_FLOAT);
            syncID = Bass.BASS_ChannelSetSync(stream, BASSSync.BASS_SYNC_END, 0, callback, IntPtr.Zero);
        }

        private void mySync(int handle, int channel, int data, IntPtr user)
        {
            NotifyEndOfStream();
        }


        event Action IPlayStream.NotifyEndOfStream
        {
            add { NotifyEndOfStream += value; }
            remove { NotifyEndOfStream -= value; }
        }

        void IPlayStream.DontNeedThisStreamAnymore()
        {
            Bass.BASS_ChannelRemoveSync(stream, syncID);
            Bass.BASS_StreamFree(stream);
        }

As u can see i am keeping callback delegate in the private filed of class so it shouldn't be collected. The problem occours more often when playing short sampless (under 1 second). I thought that possible reason could be garbage collection of whole BassHddStream whole object and tested it by adding every created BassHddStream object reference in additional List<IPlayStream> in Player instance to prevent Garbage collector from touching those objects but error still raises from time to time (about 10% chance to get error when plaing short samples) so i guess it's not the reason.

Gildarts

  • Guest
Re: CallbackOnCollectedDelegate - C# SYNCPROC
« Reply #1 on: 14 Sep '13 - 05:36 »
To prevent question its the same callback = MySync or callback = new SYNCPROC(MySync) does not solve problem

radio42

  • Posts: 4576
Re: CallbackOnCollectedDelegate - C# SYNCPROC
« Reply #2 on: 14 Sep '13 - 09:41 »
As you create a new SYNCPROC with each stream, the previous (old) one might still be in use and might get GCed in between...

Gildarts

  • Guest
Re: CallbackOnCollectedDelegate - C# SYNCPROC
« Reply #3 on: 14 Sep '13 - 14:09 »
As you create a new SYNCPROC with each stream, the previous (old) one might still be in use and might get GCed in between...

Hmm that should no happen imo cuz delegate is one of object fields so he shouldn'd get GCed unless whole object is GCed. As i sad ealier i did a test adding to player class private List <IPLayStream> adding every stream from player (ever created) to prevent GC from collecting stream objects.