Dud*_*eFX 8 c# wpf memory-leaks text-to-speech
我开发了一个项目,我想发布它使用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>
Run Code Online (Sandbox Code Playgroud)
// 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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我在Windows 7 64位上运行此程序,它将运行并最终在尝试创建新的SpeechSynthesizer对象时停止.当在Windows Vista 64位上运行时,内存将从34k的起点增长到目前为止大约400k并且在不断增长.
任何人都可以在代码中看到可能导致此问题的任何内容,或者这是Speech对象本身的问题.
任何帮助,将不胜感激.
小智 5
这是Speak方法中的一个已知问题.一个名为SPVTEXTFRAG的结构被创建并且永远不会被破坏.
详情请访问:http://connect.microsoft.com/VisualStudio/feedback/details/664196/system-speech-has-a-memory-leak
dao*_*ao 3
我可以证实这一观察。我绞尽脑汁试图找出我的程序泄漏的地方,它是 System.speech 中的 .SPEAK 方法
我已将使用基于 COM 的语音对象的应用程序转换为使用 .Net 3.5 中的新 System.Speech .Net 库。听起来像是在 .Net 应用程序中使用所有托管代码的正确方法。该应用程序突然出现了轻微的内存泄漏。
我将其分解为 2 个简单的应用程序,将“这是一个测试”转换为口语单词的 WAV 文件。一种使用基于 COM 的语音对象,另一种使用 System.Speech。我运行它们 24 小时,每个创建 WAV 大约 200,000 次。
基于 COM 的语音对象:无内存泄漏。大约 40 分钟后,应用程序的内存使用量达到峰值 13MB
System.speech:缓慢泄漏,良好且线性。24 小时内从约 14MB 增至 45MB