簡體   English   中英

如何避免Windows Phone 8.1的異步方法

[英]How to avoid async methods windows phone 8.1

我正在創建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方法,這是一種異步方法,因此在說出文字之前會顯示調用對話框。 我該如何避免呢?

async Task方法應該被接受; 只能避免使用async void方法(它們只能用作事件處理程序)。 我有一篇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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM