2012-05-06 22 views
0

我正在創建一個播放無盡音頻流的應用程序。有一個單獨的網絡服務,我可以查詢獲取當前正在播放的曲目的標題和藝術家。我想要做的是每20秒查詢一次該服務,然後相應地設置曲目標題/藝術家。目前我正在使用背景音頻播放器,以便可以在我的應用程序之外播放該流。這裏是我到目前爲止的代碼:來自AudioPlayerAgent的HttpWebRequest

public AudioPlayer() 
    { 
     if (!_classInitialized) 
     { 
      _classInitialized = true; 
      // Subscribe to the managed exception handler 
      Deployment.Current.Dispatcher.BeginInvoke(delegate 
      { 
       Application.Current.UnhandledException += AudioPlayer_UnhandledException; 

      }); 
      trackTimer = new Timer(TrackTimerTick, null, 1000, 5000); 
     } 
    } 

    public void TrackTimerTick(object state) {    
      // Create a HttpWebrequest object to the desired URL. 
      HttpWebRequest trackRequest = (HttpWebRequest)HttpWebRequest.Create("<stream url>"); 
      // Start the asynchronous request. 
      IAsyncResult result = (IAsyncResult)trackRequest.BeginGetResponse(new AsyncCallback(TrackCallback), trackRequest); 
    } 

    public void TrackCallback(IAsyncResult result) { 
     if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing && result != null) { 
      try { 
       // State of request is asynchronous. 
       HttpWebRequest trackRequest = (HttpWebRequest)result.AsyncState; 
       HttpWebResponse trackResponse = (HttpWebResponse)trackRequest.EndGetResponse(result); 
       using (StreamReader httpwebStreamReader = new StreamReader(trackResponse.GetResponseStream())) { 
        string results = httpwebStreamReader.ReadToEnd(); 
        StringReader str = new StringReader(results); 
        XDocument trackXml = XDocument.Load(str); 

        string title = (from t in trackXml.Descendants("channel") select t.Element("title").Value).First<string>(); 
        string artist = (from t in trackXml.Descendants("channel") select t.Element("artist").Value).First<string>(); 
        if (BackgroundAudioPlayer.Instance.Track != null) { 
         AudioTrack track = BackgroundAudioPlayer.Instance.Track; 
         track.BeginEdit(); 
         track.Title = title; 
         track.Artist = artist; 
         track.EndEdit(); 
        } 

       } 
       trackResponse.Close(); 
       NotifyComplete(); 
      } catch (WebException e) { 
       Debug.WriteLine(e); 
       Debug.WriteLine(e.Response); 
      } catch (Exception e) { 
       Debug.WriteLine(e); 
      } 
     } 
    } 

一個網絡異常隨時隨地,我嘗試讀取從HttpWebRequest的響應拋出。這是正確的方法嗎?有沒有人對我如何解決這個問題有什麼建議?

+0

不要捕捉異常。 http://stackoverflow.com/questions/1742940/why-not-catch-general-exceptions http://msdn.microsoft.com/en-us/library/ms182137%28v=vs.100%29.aspx –

+0

那沒有解決任何問題。 – bfink

+0

@Sedgwickz評論似乎部分解決了這個問題,我現在可以正確地獲取曲目數據。但是,一旦我呼叫NotifyComplete(),計時器不再打勾 - 有關如何解決此問題的任何提示? – bfink

回答

0

您沒有關閉HttpWebResponse,這是必需的。此外,還有一個XDocument.Load()的過載需要Stream,所以根本不需要使用StreamReader

編輯:對不起,我忽略了最後的Close()電話。但其他評論仍然適用。

如果不解決這個問題,至少它使你的代碼看起來更乾淨:

public void TrackCallback(IAsyncResult result) { 
    if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing && result != null) { 
     try { 
      // State of request is asynchronous. 
      HttpWebRequest trackRequest = (HttpWebRequest)result.AsyncState; 
      using (HttpWebResponse trackResponse = (HttpWebResponse)trackRequest.EndGetResponse(result)){ 
       XDocument trackXml = XDocument.Load(trackResponse.GetResponseStream()); 

       string title = (from t in trackXml.Descendants("channel") select t.Element("title").Value).First<string>(); 
       string artist = (from t in trackXml.Descendants("channel") select t.Element("artist").Value).First<string>(); 
       if (BackgroundAudioPlayer.Instance.Track != null) { 
        AudioTrack track = BackgroundAudioPlayer.Instance.Track; 
        track.BeginEdit(); 
        track.Title = title; 
        track.Artist = artist; 
        track.EndEdit(); 
       } 
      } 
      } 
      NotifyComplete(); 
     } catch (WebException e) { 
      Debug.WriteLine(e); 
      Debug.WriteLine(e.Response); 
     } catch (Exception e) { 
      Debug.WriteLine(e); 
     } 
    } 
} 
+0

感謝您的回覆。不幸的是它仍然不起作用,但我的代碼看起來更好:) – bfink

0

我想你應該搬來OnUserAction()的NotifyComplete()函數來你的HttpWebRequest response.Maybe這文章可以給你一些幫助:)

http://tmango.com/?p=952

0

這同AudioPlayer走出去的範圍在它開始播放音樂後做。該AudioPlayer只住了時間的一小部分,它調用NotifyComplete

後終止我的回覆這個帖子看看:後 背景聲頻線程將「暫停」: AudioPlayerAgent, timer and webservice

更多信息調用NotifyComplete。重新回到用戶改變播放時間(OnUserAction)或歌曲結束時(OnPlayStateChanged)。如果您將繼續玩,請在OnPlayStateChanged方法中獲取新信息。

+0

謝謝你的答覆。你是否在說如果我在你的回覆中引用的Songs類中創建了一個計時器,那麼這個計時器將繼續打勾? – bfink

+0

我試過這種方式,我認爲它應該可以工作,但是當我調用NotifyComplete時,定時器和任何異步HttpWebRequest調用仍然會終止。任何提示將這些放在後臺線程上,NotifyComplete被調用時不會終止? – bfink

+0

正確,請參閱我的更新 –