首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

Invoke门类的已垃圾回收委托进行了回调,这可能会导致应用程序崩溃、损坏和数据丢失求大神指导

2013-02-24 
Invoke类型的已垃圾回收委托进行了回调,这可能会导致应用程序崩溃、损坏和数据丢失求大神指导!本帖最后由 w

Invoke类型的已垃圾回收委托进行了回调,这可能会导致应用程序崩溃、损坏和数据丢失求大神指导!
本帖最后由 woshilanhan 于 2012-10-30 10:44:02 编辑 对“NAudio!NAudio.Wave.WaveInterop+WaveInCallback::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。
程序是想对麦克风的声音录取后,进行识别!
大致的代码都在下面,但是每次程序关闭时都会出现上面的错误,雪地跪求大神指导!

namespace NAudio.Wave
{
    public class WaveInStream : WaveStream
    {
        public WaveInStream(int deviceNumber, WaveFormat desiredFormat, Control callbackWindow);

        public override long Length { get; }
        public override long Position { get; set; }
        public override WaveFormat WaveFormat { get; }

        public event EventHandler<WaveInEventArgs> DataAvailable;
        public event EventHandler RecordingStopped;

        protected override void Dispose(bool disposing);
        public override int Read(byte[] buffer, int offset, int count);
        public void StartRecording();
        public void StopRecording();
    }
}

private void button3_Click(object sender, EventArgs e)
        {
            if (luyin)
            {
                luyin = false;
                isr = new ASR(c1, c2);
                isr.DataArrived += new EventHandler<FlyASR.DataArrivedEventArgs>(asr_DataAvailable);
           isr.StartRecoding();
                button3.Text = "停止录音";
            }
            else
            {
                luyin = true;
                isr.StopRecoding();
                button3.Text = "开始录音";
            }
        }





......
using NAudio.Wave;
namespace ASR
{
 public class ASR
    {
        private class ASRDll
        {
            #region ISR dllimport
            #endregion


        }
        /// <summary>
        /// 有识别数据返回的事件参数,包含了识别的文本结果
        /// </summary>
        public class DataArrivedEventArgs : EventArgs
        {
            public string result;
            public DataArrivedEventArgs(string rs)
            {
                result = rs;
            }
        }

        /// <summary>
        /// 识别数据返回的事件
        /// </summary>
        public event EventHandler<DataArrivedEventArgs> DataArrived;

        private delegate void dltSpeek(string inFile, string outfile = null);

        static private WaveInStream wis;

        /// <summary>
        /// 构造函数,初始化引擎
        public ASR(string c1, string c2)
        {
            wis = new WaveInStream(0, new WaveFormat(16000, 16, 1), null);
            wis.DataAvailable += new EventHandler<WaveInEventArgs>(wis_DataAvailable);
            int ret = 0;
            ///引擎初始化
            ret = ASRDll.QISRInit(c1);
            if (ret != 0) throw new Exception("QISP初始化失败,错误代码:" + ((ErrorCode)ret).ToString("G"));
            sess_id = Ptr2Str(ASRDll.QISRSessionBegin(string.Empty, param, ref ret));
            if (ret != 0) throw new Exception("QISRSessionBegin失败,错误代码:" + ((ErrorCode)ret).ToString("G"));
        }


        /// <summary>
        /// 进行声音识别
        /// </summary>
        /// <param name="outFile">输出识别结果到文件</param>
        public void Audio2Txt(string inFile, string outFile = null)
        {
            int ret = 0;
            string result = "";


            try
            {
                ///模拟录音,输入音频
                              
            }
        }

        #region 录音
        public void StartRecoding()
        {
            wis.StartRecording();
        }
        public void StopRecoding()
        {
            wis.StopRecording();            AudioStatus audioStatus = AudioStatus.ISR_AUDIO_SAMPLE_LAST;
            EpStatus ep_status = EpStatus.ISR_EP_NULL;
            RecogStatus rec_status = RecogStatus.ISR_REC_NULL;
            RecogStatus rslt_status = RecogStatus.ISR_REC_NULL;

            int ret = ASRDll.QISRAudioWrite(sess_id, IntPtr.Zero, 0, audioStatus, ref ep_status, ref rec_status);

            if (ret != 0) throw new Exception("QISRAudioWrite write last audio err,errCode=" + ((ErrorCode)ret).ToString("G"));

            do
            {
               
                    IntPtr p = ASRDll.QISRGetResult(sess_id, ref rslt_status, 0, ref ret);
                    try
                    {
                    if (ret != 0) throw new Exception("QISRGetResult err,errCode=" + ((ErrorCode)ret).ToString("G"));
                     }
                    catch
                    {
 System.Windows.Forms.MessageBox.Show("没有得到识别结果");
                        break;
                    }




                    if (p != IntPtr.Zero)
                    {
                        string tmp = Ptr2Str(p);
                        DataArrived(this, new DataArrivedEventArgs(tmp));//激发识别数据到达事件
                        System.Console.WriteLine("传完音频后返回结果!-->" + tmp);
                    }
               
             
                System.Threading.Thread.Sleep(200);

            } while (rslt_status != RecogStatus.ISR_REC_STATUS_SPEECH_COMPLETE);

            ret = ASRDll.QISRSessionEnd(sess_id, string.Empty);
            ret = ASRDll.QISRFini();
          

        }

        private void wis_DataAvailable(object sender, WaveInEventArgs e)
        {
            System.Console.WriteLine(System.DateTime.Now + ":" + System.DateTime.Now.Millisecond);

            int ret = 0;
            IntPtr bp = Marshal.AllocHGlobal(e.BytesRecorded);
            AudioStatus status = AudioStatus.ISR_AUDIO_SAMPLE_CONTINUE;
            EpStatus ep_status = EpStatus.ISR_EP_NULL;
            RecogStatus rec_status = RecogStatus.ISR_REC_NULL;
            RecogStatus rslt_status = RecogStatus.ISR_REC_NULL;
            ///ep_status        端点检测(End-point detected)器所处的状态
            ///rec_status       识别器所处的状态
            ///rslt_status      识别器所处的状态
            Marshal.Copy(e.Buffer, 0, bp, e.BytesRecorded);
            ///开始向服务器发送音频数据
            ret = ASRDll.QISRAudioWrite(sess_id, bp, (uint)e.BytesRecorded, status, ref ep_status, ref rec_status);
            try


            {
            if (ret != 0) throw new Exception("QISRAudioWrite err,errCode=" + ((ErrorCode)ret).ToString("G"));

                ///服务器返回部分结果
                if (rec_status == RecogStatus.ISR_REC_STATUS_SUCCESS)
                {
                    IntPtr p = ASRDll.QISRGetResult(sess_id, ref rslt_status, 0, ref ret);
                    if (p != IntPtr.Zero)
                    {
                        string tmp = Ptr2Str(p);
                        DataArrived(this, new DataArrivedEventArgs(tmp));//激发识别数据到达事件
                        System.Console.WriteLine("服务器返回部分结果!-->" + tmp);
                    }
                }

            }
            catch(Exception ex)
            {
                System.Console.WriteLine("结束异常{0}" + ex);
            }
            System.Threading.Thread.Sleep(500);
            Marshal.FreeHGlobal(bp);
            //System.Console.WriteLine(System.DateTime.Now + ":" + System.DateTime.Now.Millisecond);
        }
        #endregion

        /// <summary>
        /// 指针转字符串
        /// </summary>
        /// <param name="p">指向非托管代码字符串的指针</param>
        /// <returns>返回指针指向的字符串</returns>
        private string Ptr2Str(IntPtr p)
        {
            List<byte> lb = new List<byte>();
            while (Marshal.ReadByte(p) != 0)
            {
                lb.Add(Marshal.ReadByte(p));


                p = p + 1;
            }
            byte[] bs = lb.ToArray();
            return Encoding.Default.GetString(lb.ToArray());
        }
    }}



[解决办法]
你给我个邮箱,我给你传些资料,以前我也遇到这个问题。

热点排行