如何在C#中将异步方法与同步方法结合起来?

3
我从主方法调用:

public MainPage()
{
  Text_to_Speech.changetospeech("Welcome to Nepal!", newmedia).Wait();
  mytxtblck.Text="Hello from Nepal!"
}

我真正想做的是等到“欢迎来到尼泊尔”被说出来,然后在mytextblck中写入“Hello”。

我已经去了几个线程并努力工作,但没有任何东西能够让它工作。

public async static Task changetospeech(string text, MediaElement mediaa)
{
   var synth = new SpeechSynthesizer();
   var voices = SpeechSynthesizer.AllVoices;

   synth.Voice = voices.First(x => x.Gender == VoiceGender.Female );
   SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync(text);

   MediaElement media = mediaa;
   media.SetSource(stream,stream.ContentType);
   media.Play();   
}
1个回答

7

听起来你真正想要的是当触发MediaEnded事件时改变文本。

虽然在ChangeToSpeech方法中可以实现,但这样有点不好看:

public async static Task ChangeToSpeech(string text, MediaElement media)
{
    var synth = new SpeechSynthesizer();
    var voices = SpeechSynthesizer.AllVoices;

    synth.Voice = voices.First(x => x.Gender == VoiceGender.Female);

    SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync(text);

    var tcs = new TaskCompletionSource<int>();
    RoutedEventHandler handler = delegate { tcs.TrySetResult(10); };
    media.MediaEnded += handler;
    try
    {
        media.SetSource(stream, stream.ContentType);
        media.Play();
        // Asynchronously wait for the event to fire
        await tcs.Task;
    }
    finally
    {
        media.MediaEnded -= handler;
    }
}

Task.FromResultTaskCompletionSource 更好吗? - Mrinal Kamboj
1
@MrinalKamboj:你会如何使用它来解决手头的问题?它如何帮助你异步等待事件触发? - Jon Skeet
1
@MrinalKamboj:不会的。这将立即完成,使等待无意义。使用TCS的整个重点在于我们可以在事件处理程序中设置它。再次问一下,您的解决方案如何帮助我们异步等待“media.MediaEnded”触发?(这才是代码的全部意义...) - Jon Skeet
@JonSkeet 懂了,谢谢。我原本以为 Task.FromResultTaskCompletionSource 的替代品,但现在看来只适用于模拟和单元测试。 - Mrinal Kamboj
@MrinalKamboj:我并没有说它在模拟方面没有用处...但是在许多情况下,您可能已经在生产代码中有一个值。想象一下计算缓存,您可以请求一个值-如果它已经有该值,则可以返回Task.OfResult,如果需要计算结果,则可以调用实际的异步方法。 - Jon Skeet
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接