微软语音动态库SpeechLib的内存溢出问题? 10C

在使用微软语音合成动态库SpeechLib时,发现一个问题,就是使用过程中发内存在不断增加,在实际应用中,大概经过2000多次的,catch异常:
Exception of type 'System.OutOfMemoryException' was thrown.我也百度过,一位仁兄提到过此问题,但是回答说这个问题无解,给出的方案是只能过一段时间,重启程序,这也是一个不得已方法。有没有s什么很好的解决方法呢?求教各位高手?贴源代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SpeechLib;
namespace SimpleTTS
{
public class TtsController:ITts
{
private readonly SpVoice _SPVoice;
private readonly SpeechVoiceSpeakFlags _SpFlags ;
public TtsController()
{
if (_SpFlags == null)
_SpFlags = SpeechVoiceSpeakFlags.SVSFlagsAsync;
if (_SPVoice == null)
_SPVoice = new SpVoice();
_SPVoice.Rate = -1;
string LibVoice = "Microsoft Lili - Chinese (China)";
ISpeechObjectTokens obj = _SPVoice.GetVoices();
int count = obj.Count;//获取语音库总数

for (int i = 0; i < count; i++)
{
string desc = obj.Item(i).GetDescription(); //遍历语音库

            if (desc.Equals(LibVoice))
            {

                _SPVoice.Voice =   obj.Item(i);
                break;
            }
         }
    }

    public void Speak(string text)
    {
        try
        { 
            _SPVoice.Speak(text, _SpFlags);

        }
        catch (Exception ex)
        {
            throw   ex;
        }
    }

    public void Resume()
    {
        try
        {

            _SPVoice.Resume(); 
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    public void Stop()
    {
        try
        {

            _SPVoice.Pause();
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

}

}
调用:
private readonly object _lock_vioce = new object();
private TtsController TTSControllers = new TtsController();
///
/// 播放文字的语音
///
///
private void Speaker(object obj)
{
lock (_lock_vioce)
{
string text = (string)obj;
TTSControllers.Speak(text);
}
}
for(int i=0;i<10000;i++)
{
try
{

                Thread thread_voice = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Speaker));
                thread_voice.IsBackground = true;
                thread_voice.Start("你好"); 
                Thread.Sleep(1000);
                Application.DoEvents();

            }
            catch (Exception ex)
            {

                WriteLog(ex.Message); 
            }
        }
                    }

3个回答

Speaker方法放在界面线程里可以解决么?com对象的内存溢出原因比较复杂,很可能和线程有关,或者内部有bug

m0_37874882
m0_37874882 c++调用过,没有发现此问题。很有可能是其他地方的代码引起的
接近 2 年之前 回复
zhaoyipei1977
看淡烟云 在界面线程也是一样,比如,我在timer里,一样是这样的问题。不知道这是什么机制,也不自动释放资源,也不提供释放资源的接口。我觉得这是个严重的问题,网上竟然没有太多的反应,很奇怪
接近 2 年之前 回复

c++调用过,没有发现此问题。很有可能是其他地方的代码引起的

Thread类有一个IsBackground 的属性,它的解释是:获取或设置一个值,该值指示某个线程是否为后台线程。线程可以分为后台线程和前台线程。后台线程与前台线程并没有本质的区别,就是:后台线程不会防止应用程序的进程被终止掉。其实,说白了就是当前台线程都结束了的时候,整个程序也就结束了,即使还有后台线程正在运行,此时,所有剩余的后台线程都会被停止且不会完成。但是,只要还有一个前台线程没有结束,那么它将阻止程序结束。这就是为什么有些设计不够完美的程序,在某种特定的情况下,即使所有的窗口都关闭了,但是在任务管理器的管理列表里仍然可以找到该程序的进程,仍然在消耗着CPU和内存资源.因此,在程序中,关闭所有窗口前,应该停止所有前台线程,千万不要遗忘了某个前台线程。应用程序进程的存亡由前台线程决定而于后台线程无关.这就是它们的区别。所以:
1、当在主线程中创建了一个线程,那么该线程的IsBackground默认是设置为FALSE的。
2、当主线程退出的时候,IsBackground=FALSE的线程结束。
3、只有IsBackground=TRUE的线程才会随着主线程的退出而阻止结束,继续占用资源。
4、当初始化一个线程,把Thread.IsBackground=true的时候,指示该线程为后台线程。后台线程将会随着主线程的退出而阻止结束,继续占用资源。
5、原理:只要所有前台线程都终止前,系统就要对每一个活在的后台线程调用Abort()来彻底终止应用程序。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!