首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在2012年R2上,System.Speech.Synthesis挂起,CPU较高

在2012年R2上,System.Speech.Synthesis挂起,CPU较高
EN

Stack Overflow用户
提问于 2015-08-27 05:21:27
回答 4查看 1.3K关注 0票数 17

我有一个asp.net MVC应用程序,它有一个控制器操作,它接受字符串作为输入,并发送合成语音的响应wav文件。下面是一个简化的示例:

代码语言:javascript
复制
    public async Task<ActionResult> Speak(string text)
    {
        Task<FileContentResult> task = Task.Run(() =>
        {
            using (var synth = new System.Speech.Synthesis.SpeechSynthesizer())
            using (var stream = new MemoryStream())
            {
                synth.SetOutputToWaveStream(stream);
                synth.Speak(text);
                var bytes = stream.GetBuffer();
                return File(bytes, "audio/x-wav");
            }
        });
        return await task;
    }

该应用程序(特别是此操作方法)在2008 R2服务器、2012 (非R2)服务器和我的8.1dev PC上的服务器环境中运行良好。它也可以在标准的Azure 2012 R2虚拟机上运行良好。然而,当我将它部署到三个2012CPUServer(它最终的永久宿主)上时,该操作方法从未生成R2响应-- IIS进程无限期地占用了其中一个CPU核心。事件查看器中没有任何内容,当我使用Procmon查看服务器时,也没有任何东西跳出来。我已经通过远程调试附加到进程,但synth.Speak(text)再也没有返回。当执行synth.Speak(text)调用时,我会立即在服务器的任务管理器中看到失控的w3wp.exe进程。

我的第一个倾向是认为一些进程干扰了服务器上的语音合成,但Windows讲述人工作正常,这样一个简单的控制台应用程序也可以正常工作:

代码语言:javascript
复制
static void Main(string[] args)
{
    var synth = new System.Speech.Synthesis.SpeechSynthesizer();
    synth.Speak("hello");
}

所以很明显,我不能责怪服务器的语音合成。那么,也许我的代码中有问题,或者IIS配置中有什么奇怪的东西?如何才能使此控制器操作在这些服务器上正常工作?

这是一种测试操作方法的简单方法(只需为路由获得正确的url值):

代码语言:javascript
复制
<div>
    <input type="text" id="txt" autofocus />
    <button type="button" id="btn">Speak</button>
</div>

<script>
    document.getElementById('btn').addEventListener('click', function () {
        var text = document.getElementById('txt').value;
        var url = window.location.href + '/speak?text=' + encodeURIComponent(text);
        var audio = document.createElement('audio');
        var canPlayWavFileInAudioElement = audio.canPlayType('audio/wav'); 
        var bgSound = document.createElement('bgsound');
        bgSound.src = url;
        var canPlayBgSoundElement = bgSound.getAttribute('src');

        if (canPlayWavFileInAudioElement) {
            // probably Firefox and Chrome
            audio.setAttribute('src', url);
            audio.setAttribute('autoplay', '');
            document.getElementsByTagName('body')[0].appendChild(audio);
        } else if (canPlayBgSoundElement) {
            // internet explorer
            document.getElementsByTagName('body')[0].appendChild(bgSound);
        } else {
            alert('This browser probably can\'t play a wav file');
        }
    });
</script>
EN

回答 4

Stack Overflow用户

发布于 2015-08-27 05:36:50

我认为问题出在返回类型上。IIS Express可以让您逃脱惩罚,但IIS不能:

代码语言:javascript
复制
Task<FileContentResult>

因此,如果你尝试:

代码语言:javascript
复制
public async Task<FileContentResult> Speak(string text)
{
    Task<FileContentResult> task = Task.Run(() =>
    {
        using (var synth = new System.Speech.Synthesis.SpeechSynthesizer())
        using (var stream = new MemoryStream())
        {
            synth.SetOutputToWaveStream(stream);
            synth.Speak(text);
            var bytes = stream.GetBuffer();
            return File(bytes, "audio/x-wav");
        }
    });
    return await task;
}

我打赌您还需要在IIS中添加音频/wav MIME类型。

票数 1
EN

Stack Overflow用户

发布于 2015-10-08 01:47:48

我以前有过使用服务器2012R2的经验(不是授予synth api,但有相同的问题)。我通过在我的所有任务上使用"await task.ConfigureAwait(false)“修复了这个问题。看看这对你是不是有用。

祝好运。

票数 1
EN

Stack Overflow用户

发布于 2015-10-09 17:45:24

this blog上,你可以找到一个类似问题的解决方案-在全新安装的Windows8.1上使用SpeechSynthesizer时出现异常。这种情况下的问题是CurrentUserLexicon用户(由SpeechSynthesizer使用)的权限条目错误。要解决此问题,此博客帖子建议从Software\Microsoft\Speech\CurrentUserLexicon注册表项中删除权限条目“所有应用程序包”。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32236923

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档