2012-03-10 4 views
1

온라인 스트림에서 음악을 재생하는 백그라운드 오디오 에이전트를 작성하고 트랙 이름과 아티스트의 업데이트를 주기적으로 확인합니다. HttpWebRequest 객체를 사용하여 이름과 아티스트를 가져 오려고 시도하지만, HttpWebResponse trackResponse = (HttpWebResponse)trackRequest.EndGetResponse(result);을 호출 할 때마다 아래 오류가 발생합니다. 그에 더HttpWebRequest가 null을 반환합니다. ResponseStatusCode

ResponseStatusCode = 'trackRequest.ResponseStatusCode' threw an exception of type 'System.NullReferenceException'

및 다음 trackRequest 객체로 더 파고

at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state) 
at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult) 
at AudioPlaybackAgent.AudioPlayer.TrackCallback(IAsyncResult result) 
at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClassa.<InvokeGetResponseCallback>b__8(Object state2) 
at System.Threading.ThreadPool.WorkItem.WaitCallback_Context(Object state) 
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
at System.Threading.ThreadPool.WorkItem.doWork(Object o) 
at System.Threading.Timer.ring() 

, 나는이 문제를 찾을 수 :

A first chance exception of type 'System.Net.WebException' occurred in System.Windows.dll

WebException이에 대한 스택 추적은 다음과 같다 , 나는 이것을 발견한다 :

at System.Net.HttpWebRequest.get_ResponseStatusCode() 
at AudioPlaybackAgent.AudioPlayer.TrackCallback(IAsyncResult result) 
at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClassa.<InvokeGetResponseCallback>b__8(Object state2) 
at System.Threading.ThreadPool.WorkItem.WaitCallback_Context(Object state) 
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
at System.Threading.ThreadPool.WorkItem.doWork(Object o) 
at System.Threading.Timer.ring() 

다음은 현재 사용중인 코드입니다. TrackTimerTick 함수는 Timer에 의해 매 20 초마다 호출됩니다.

public static void TrackTimerTick(object state) { 
     try { 
      if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing) { 
       // Create a HttpWebrequest object to the desired URL. 
       HttpWebRequest trackRequest = (HttpWebRequest)HttpWebRequest.Create("<track/artist url"); 
       // Start the asynchronous request. 
       IAsyncResult result = (IAsyncResult)trackRequest.BeginGetResponse(new AsyncCallback(TrackCallback), trackRequest); 
      } 
     } catch (WebException e) { 
      Debug.WriteLine(e.Message); 
     } catch (Exception e) { 
      Debug.WriteLine(e.Message); 
     } 
    } 


    public static void TrackCallback(IAsyncResult result) { 
     // State of request is asynchronous. 
     HttpWebRequest trackRequest = (HttpWebRequest)result.AsyncState; 
     HttpWebResponse trackResponse = (HttpWebResponse)trackRequest.EndGetResponse(result); // WebException thrown here 

     using (StreamReader httpwebStreamReader = new StreamReader(trackResponse.GetResponseStream())) { 
      string results = httpwebStreamReader.ReadToEnd(); 
      XDocument trackXml = XDocument.Load(results); 

      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(); 


    } 

누구든지이 문제를 해결할 수 있습니까? 미리 감사드립니다.

+0

두 스레드에서 응답 상태에 액세스하지 않는 것입니까? – Cameron

+0

TrackCallback이 응답을 참조하는 유일한 장소이기 때문에 저는 그렇게 믿지 않습니다. – bfink

답변

0

문제는 응답이 도착하기 전에 NotifyComplete()를 호출하는 것이 문제입니다. 무슨 일이 벌어지는 지 완전히 이해할 수는 없지만 요청을 시작하고 NotifyComplete를 호출하면 OS가 에이전트의 프로세스를 멈추게합니다. 그런 다음 에이전트가 다음 번에 WebClient를 깨우면 즉시 예외가 발생합니다.

그래서 해결책은 응답을받을 때까지 NotifyComplete를 호출하지 않는 것입니다.

+0

더 자세히 설명해 주시겠습니까? NotifyComplete()를 옮겨 보았고 트랙 텍스트를 가져올 수 있도록 관리했지만 인앱 일시 중지 버튼을 클릭하면 음악이 일시 중지되지 않았습니다. 좀 더 제안 해 주시겠습니까? – bfink

+0

음, 나는 오디오 배경 에이전트를 전혀 쓴 적이 없다. 적절한 시간에 NotifyComplete를 호출하지 않는 것이 가장 좋다. 문제가 될 수있는 첫 번째 일은 타이머를 사용하는 것입니다. 제어 명령간에 프로세스가 고정되어 있으므로 타이머의 틱 이벤트는 명령간에 실행되지 않습니다. 당신이 정말로 오디오 에이전트에서 웹 요청을하고 싶다면 (나도 잘 모르겠다. 정말로 필요하다.) PlayStateChanged에서 요청을 시작하고 응답 콜백에서 NotifyComplete를 호출 해 보라. 더 많은 정보가 없으면 이것은 나의 가장 좋은 생각입니다. –

+0

감사합니다. 오디오 에이전트를 시작한 주 응용 프로그램이 비활성화 된 경우에도 새 백그라운드 데이터를 얻으려면 매 20-30 초마다 오디오 백그라운드 에이전트에서 서버에 쿼리하도록하고 싶습니다. 이것이 가능한가? – bfink

관련 문제