我开发了一个我想发布的项目,它使用 c#、WPF 和 System.Speech.Synthesizer 对象。阻止该项目发布的问题是,每当调用 SpeakAsync 时,它都会留下内存泄漏,并最终导致失败。我相信我在使用此物品后已正确清理,但找不到治疗方法。我已经通过 Ants Memory Profiler 运行了该程序,它报告说 WAVEHDR 和 WaveHeader 在每次调用时都在增长。
我创建了一个示例项目来尝试查明原因,但仍然不知所措。任何帮助,将不胜感激。
该项目使用 VS2008 并且是针对 .NET 3.5 和 Any CPU 的 ac# 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 对象本身的问题。
任何帮助,将不胜感激。