Постоянная утечка памяти в SpeechSynthesizer

Я разработал проект, который я хотел бы выпустить который использование c#, WPF и Система. Речь. Объект синтезатора. Проблема, предотвращающая выпуск этого проекта, - то, что каждый раз, когда SpeakAsync называют, он оставляет утечку памяти, которая растет на грани возможного отказа. Я полагаю, что вымылся правильно после использования этого объекта, но не могу найти средство исправления. Я запустил программу через Профилировщика Памяти Муравьев, и она сообщает, что WAVEHDR и WaveHeader растут с каждым вызовом.

Я создал демонстрационный проект попытаться точно определить причину, но все еще в недоумении. Любая справка ценилась бы.

Проект использует VS2008 и является c# WPF проект, который предназначается для.NET 3.5 и Любой ЦП. Необходимо вручную добавить ссылку на Систему. Речь.

Вот Код:

<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 и росте.

Может любой видеть что-либо в коде, который мог бы вызывать это или является этим проблема с самим Речевым объектом.

Любая справка ценилась бы.

8
задан Dave Clemmer 18 September 2011 в 17:52
поделиться

2 ответа

Я могу подтвердить это наблюдение. Я рвал за волосы, пытаясь выяснить, где утекает моя программа, и это метод .SPEAK в System.speech

. Я преобразовал приложение, которое использовало объекты Speech на основе COM, для использования нового System.Speech. Net-библиотека в .Net 3.5. Звучит как правильный способ перейти к использованию всего управляемого кода в приложении .Net. В приложении внезапно произошла небольшая утечка памяти.

Я разбил это на 2 простых приложения, которые конвертируют «это тест» в WAV-файл произнесенных слов. Один использует речевые объекты на основе COM, другой - System.Speech. Я запускал их в течение 24 часов, каждый из которых создавал WAV около 200 000 раз.

Речевые объекты на основе COM: нет утечки памяти. Примерно через 40 минут объем памяти приложения достиг 13 МБ

System.speech: медленная утечка, приятная и линейная. Увеличилось с 14 до 45 МБ за 24 часа

3
ответ дан 5 December 2019 в 17:37
поделиться

SendAsync() из Ping также дает утечки. Решение состоит в том, чтобы сначала указать отправителя как IDisposable. Так что, возможно, здесь также работает следующее.

((IDisposable)spk).Dispose();
2
ответ дан 5 December 2019 в 17:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: