在静态类中检测到CallbackOnCollectedDelegate

时间:2015-01-07 08:24:07

标签: c#

这是Wave类,可在许多站点上使用。我在我的一个项目中使用了这个类,它在+20台计算机上运行以进行调试。 一切都很好,但有时候当用户向其注入大量任务时程序停止工作,然后崩溃将在上面的类中产生。

我在互联网上研究了很多类似的问题,也在这个网站上发了所有类似的帖子。大多数情况下这些情况都有同样的问题,但我无法解决。

using System;
using System.Runtime.InteropServices;
namespace SoundViewer
{
public enum WaveFormats
{
    Pcm = 1,
    Float = 3
}

[StructLayout(LayoutKind.Sequential)]
public class WaveFormat
{
    public short wFormatTag;
    public short nChannels;
    public int nSamplesPerSec;
    public int nAvgBytesPerSec;
    public short nBlockAlign;
    public short wBitsPerSample;
    public short cbSize;

    public WaveFormat(int rate, int bits, int channels)
    {
        wFormatTag = (short)WaveFormats.Pcm;
        nChannels = (short)channels;
        nSamplesPerSec = rate;
        wBitsPerSample = (short)bits;
        cbSize = 0;

        nBlockAlign = (short)(channels * (bits / 8));
        nAvgBytesPerSec = nSamplesPerSec * nBlockAlign;
    }
}

internal class WaveNative
{
    // consts
    public const int MMSYSERR_NOERROR = 0; // no error

    public const int MM_WOM_OPEN = 0x3BB;
    public const int MM_WOM_CLOSE = 0x3BC;
    public const int MM_WOM_DONE = 0x3BD;

    public const int MM_WIM_OPEN = 0x3BE;
    public const int MM_WIM_CLOSE = 0x3BF;
    public const int MM_WIM_DATA = 0x3C0;

    public const int CALLBACK_FUNCTION = 0x00030000;    // dwCallback is a FARPROC 

    public const int TIME_MS = 0x0001;  // time in milliseconds 
    public const int TIME_SAMPLES = 0x0002;  // number of wave samples 
    public const int TIME_BYTES = 0x0004;  // current byte offset 

    // callbacks
    public delegate void WaveDelegate(IntPtr hdrvr, int uMsg, int dwUser, ref WaveHdr wavhdr, int dwParam2);

    // structs 

    [StructLayout(LayoutKind.Sequential)]
    public struct WaveHdr
    {
        public IntPtr lpData; // pointer to locked data buffer
        public int dwBufferLength; // length of data buffer
        public int dwBytesRecorded; // used for input only
        public IntPtr dwUser; // for client's use
        public int dwFlags; // assorted flags (see defines)
        public int dwLoops; // loop control counter
        public IntPtr lpNext; // PWaveHdr, reserved for driver
        public int reserved; // reserved for driver
    }

    private const string mmdll = "winmm.dll";

    // WaveOut calls
    [DllImport(mmdll)]
    public static extern int waveOutGetNumDevs();
    [DllImport(mmdll)]
    public static extern int waveOutPrepareHeader(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
    [DllImport(mmdll)]
    public static extern int waveOutUnprepareHeader(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
    [DllImport(mmdll)]
    public static extern int waveOutWrite(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
    [DllImport(mmdll)]
    public static extern int waveOutOpen(out IntPtr hWaveOut, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
    [DllImport(mmdll)]
    public static extern int waveOutReset(IntPtr hWaveOut);
    [DllImport(mmdll)]
    public static extern int waveOutClose(IntPtr hWaveOut);
    [DllImport(mmdll)]
    public static extern int waveOutPause(IntPtr hWaveOut);
    [DllImport(mmdll)]
    public static extern int waveOutRestart(IntPtr hWaveOut);
    [DllImport(mmdll)]
    public static extern int waveOutGetPosition(IntPtr hWaveOut, out int lpInfo, int uSize);
    [DllImport(mmdll)]
    public static extern int waveOutSetVolume(IntPtr hWaveOut, int dwVolume);
    [DllImport(mmdll)]
    public static extern int waveOutGetVolume(IntPtr hWaveOut, out int dwVolume);

    // WaveIn calls
    [DllImport(mmdll)]
    public static extern int waveInGetNumDevs();
    [DllImport(mmdll)]
    public static extern int waveInAddBuffer(IntPtr hwi, ref WaveHdr pwh, int cbwh);
    [DllImport(mmdll)]
    public static extern int waveInClose(IntPtr hwi);
    [DllImport(mmdll)]
    public static extern int waveInOpen(out IntPtr phwi, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
    [DllImport(mmdll)]
    public static extern int waveInPrepareHeader(IntPtr hWaveIn, ref WaveHdr lpWaveInHdr, int uSize);
    [DllImport(mmdll)]
    public static extern int waveInUnprepareHeader(IntPtr hWaveIn, ref WaveHdr lpWaveInHdr, int uSize);
    [DllImport(mmdll)]
    public static extern int waveInReset(IntPtr hwi);
    [DllImport(mmdll)]
    public static extern int waveInStart(IntPtr hwi);
    [DllImport(mmdll)]
    public static extern int waveInStop(IntPtr hwi);
}
}

上述名称空间的成员多次使用不同的表格。

错误: 对收集的'SoundProcessing'类型的垃圾进行了回调! SoundViewer.WaveNative + WaveDelegate ::调用”。这可能会导致应用程序崩溃,损坏和数据丢失。将委托传递给非托管代码时,托管应用程序必须保持活动状态,直到确保它们永远不会被调用为止。

似乎问题出在委托回调(//回拨线路)上,解决办法是保持活着,但是如何?! 这是最好的解决方案吗?其他解决方案怎么样? 感谢。

许多网站都提供完整的程序源,包括以下链接 http://www.4shared.com/folder/WoM9Hkzp/SourceSample.html

0 个答案:

没有答案