我已经开发了一个项目,我想发布它使用c#,WPF和System.Speech.Synthesizer对象。阻止此项目发布的问题是,每当调用SpeakAsync时,它都会留下内存泄漏,直到最终失败。我相信我在使用这个对象后已经清理干净了,但是找不到解决方法。我已经通过Ants内存分析器运行了这个程序,它报告WAVEHDR和WaveHeader随着每次调用而增长。
我已经创建了一个示例项目,试图找出原因,但仍然不知所措。任何帮助都将不胜感激。
该项目使用VS2008,是一个c# WPF项目,目标是.NET 3.5和任何.NET。您需要手动添加对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();
}
}
}
}
我在64位的Windows7上运行这个程序,当我尝试创建一个新的SpeechSynthesizer对象时,它将运行并最终停止。当在64位Windows Vista上运行时,内存将从34k的起始点增长到目前的大约400k,而且还在不断增长。
是否有人可以在代码中看到可能导致此问题的任何内容,或者这是Speech对象本身的问题。
任何帮助都将不胜感激。
发布于 2011-09-18 03:41:23
这是Speak方法中的一个已知问题。一个名为SPVTEXTFRAG的结构被创建,并且永远不会被销毁。
详情请访问:http://connect.microsoft.com/VisualStudio/feedback/details/664196/system-speech-has-a-memory-leak
发布于 2010-03-14 20:56:26
我可以证实这一点。我费了九牛二虎之力,试图找出我的程序泄漏在哪里,那就是System.speech中的.SPEAK方法
我已经将一个使用基于COM的Speech对象的应用程序转换为使用.Net 3.5中新的System.Speech .Net库。这听起来像是在.Net应用程序中使用所有管理代码的正确方式。这个应用程序突然出现了一个小的内存泄漏。
我把它分解成两个简单的应用程序,将“这是一个测试”转换为一个WAV文件的口语。一个使用基于COM的speech对象,另一个使用System.Speech。我运行了24小时,每次创建WAV大约200,000次。
基于COM的语音对象:没有内存泄漏。app内存使用率在约40分钟后达到13MB峰值
System.speech:缓慢泄漏,良好且线性。在24小时内从14MB增加到45MB
发布于 2010-08-26 09:26:51
来自Ping
的SendAsync()
也会泄露。这里的解决方案是首先将发送者转换为IDisposable
。因此,也许下面的方法也适用于这里。
((IDisposable)spk).Dispose();
https://stackoverflow.com/questions/2204012
复制相似问题