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());
}
}}
[解决办法]
你给我个邮箱,我给你传些资料,以前我也遇到这个问题。