我开发了一个我想发布的项目,它使用c#,WPF和System.Speech.Synthesizer对象。防止此项目发布的问题是,无论何时调用SpeakAsync,都会留下内存泄漏,从而导致最终失败。我相信在使用这个对象后我已经清理好了,但是找不到治疗方法。我已经通过蚂蚁内存分析器运行该程序,并且报告说每次调用WAVEHDR和WaveHeader都在增长。SpeechSynthesizer中的常量内存泄漏
我已经创建了一个示例项目来试图找出原因,但我仍然处于亏损状态。任何帮助,将不胜感激。
该项目使用VS2008,是一个面向.NET 3.5和任何CPU的c#WPF项目。您需要手动添加对System.Speech的引用。
这里是代码:
<Window x:Class="SpeechTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<StackPanel Orientation="Vertical">
<Button Content="Start Speaking" Click="Start_Click" Margin="10" />
<Button Content="Stop Speaking" Click="Stop_Click" Margin="10" />
<Button Content="Exit" Click="Exit_Click" Margin="10"/>
</StackPanel>
</Grid>
// Start of code behind
using System;
using System.Windows;
using System.Speech.Synthesis;
namespace SpeechTest
{
public partial class Window1 : Window
{
// speak setting
private bool speakingOn = false;
private int curLine = 0;
private string [] speakLines = {
"I am wondering",
"Why whenever Speech is called",
"A memory leak occurs",
"If you run this long enough",
"It will eventually crash",
"Any help would be appreciated" };
public Window1()
{
InitializeComponent();
}
private void Start_Click(object sender, RoutedEventArgs e)
{
speakingOn = true;
SpeakLine();
}
private void Stop_Click(object sender, RoutedEventArgs e)
{
speakingOn = false;
}
private void Exit_Click(object sender, RoutedEventArgs e)
{
App.Current.Shutdown();
}
private void SpeakLine()
{
if (speakingOn)
{
// Create our speak object
SpeechSynthesizer spk = new SpeechSynthesizer();
spk.SpeakCompleted += new EventHandler(spk_Completed);
// Speak the line
spk.SpeakAsync(speakLines[curLine]);
}
}
public void spk_Completed(object sender, SpeakCompletedEventArgs e)
{
if (sender is SpeechSynthesizer)
{
// get access to our Speech object
SpeechSynthesizer spk = (SpeechSynthesizer)sender;
// Clean up after speaking (thinking the event handler is causing the memory leak)
spk.SpeakCompleted -= new EventHandler(spk_Completed);
// Dispose the speech object
spk.Dispose();
// bump it
curLine++;
// check validity
if (curLine >= speakLines.Length)
{
// back to the beginning
curLine = 0;
}
// Speak line
SpeakLine();
}
}
}
}
我在Windows上运行这个程序7 64位,它会运行,并试图创建一个新的SpeechSynthesizer对象时最终停止。在Windows Vista 64位上运行时,内存将从34k的起点增长到目前的大约400k,并在不断增长。
任何人都可以在代码中看到可能导致此问题的任何内容,或者这是Speech对象本身的问题。
任何帮助,将不胜感激。
你确定它不断上升?内存将继续以.net的速度增长,直到GC通过并清理事件。除非它不断上升,永远不会下降,那么我不会担心它。 – 2010-02-04 23:37:28
是的,当我在Windows 7上运行它时,它最终会在试图创建新的SpeechSynthesizer对象时停止。在程序暂停后,去控制面板并尝试测试文本到语音的结果会一样。在机器重新启动之前,它不会说话。 – DudeFX 2010-02-04 23:44:08
如果您不在每次传递中创建新的SpeechSynthesizer对象,会发生什么情况? – 2010-02-19 20:50:58