如何避免异步方法windows phone 8.1

本文关键字:phone windows 何避免 异步方法 | 更新日期: 2023-09-27 18:20:53

我正在创建一个windows phone 8.1应用程序。当应用程序启动时,应用程序会提示用户拨打特定的电话号码。它通过声音来做到这一点。应用程序告知指令后,会显示通话对话框。这是代码:

public MainPage()
    {
        this.InitializeComponent();
        this.NavigationCacheMode = NavigationCacheMode.Required;
        StartSpeaking("Please call number !");
        CallDialog();
    }
    private async void StartSpeaking(string text)
    {
        MediaElement mediaElement = this.media;
        // The object for controlling the speech synthesis engine (voice).
        var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
        // Generate the audio stream from plain text.
        SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync(text);
        // Send the stream to the media object.
         mediaElement.SetSource(stream, stream.ContentType);
        mediaElement.Play();

    }
 private async void CallDialog()
    {
        Windows.ApplicationModel.Calls.PhoneCallManager.ShowPhoneCallUI("123", "123");
        var messageDialog = new Windows.UI.Popups.MessageDialog("call ended", "Text spoken");
        await messageDialog.ShowAsync();
    }

问题是我必须使用synth。SynthesizeTextToStreamAsync方法是一种异步方法,所以在说出文本之前会显示调用对话框。我该如何避免这种情况?

如何避免异步方法windows phone 8.1

async Task方法应该被接受;应该避免的只有CCD_ 2方法(它们只能用作事件处理程序)。我有一篇MSDN文章描述了避免async void的几个原因。

在您的情况下,您可以使用async void事件处理程序(例如,用于Loaded事件),并将方法设为async Task而不是async voidawait

async void MainPage_Loaded(..)
{
  await StartSpeakingAsync("Please call number !");
  await CallDialogAsync();
}
private async Task StartSpeakingAsync(string text);
private async Task CallDialogAsync();

更新

要(异步)等待媒体播放,您需要挂接一个事件,通知您播放完成。MediaEnded看起来是个不错的选择。像这样的东西应该起作用:

public static Task PlayToEndAsync(this MediaElement @this)
{
  var tcs = new TaskCompletionSource<object>();
  RoutedEventHandler subscription = null;
  subscription = (_, __) =>
  {
    @this.MediaEnded -= subscription;
    tcs.TrySetResult(null);
  };
  @this.MediaEnded += subscription;
  @this.Play();
  return tcs.Task;
}

该方法用async就绪的PlayToEndAsync方法扩展了MediaElement,您可以这样使用它:

private async Task SpeakAsync(string text)
{
  MediaElement mediaElement = this.media;
  var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
  SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync(text);
  mediaElement.SetSource(stream, stream.ContentType);
  await mediaElement.PlayToEndAsync();
}