2014-11-09 3 views
0

Windows Phone 8 앱에서 POST 메서드를 사용하여 RESTfull 서비스를 호출하고 싶습니다. 따라서 JSON으로 파싱 한 후 요청 본문에 보내려는 데이터를 삽입해야합니다. 이렇게하려면 다음 코드를 사용했습니다 :Windows Phone에서 작업 스레드의 UI 스레드에서 값을 가져 오는 방법?

enter cprivate void NextArrow_Tap(object sender, System.Windows.Input.GestureEventArgs e) 
    { 
     if (!String.IsNullOrEmpty(TxtBox_mail.Text)) 
     { 
      Uri myUri = new Uri("http://myUri"); 
      HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(myUri); 
      myRequest.Method = "POST"; 
      myRequest.ContentType = "application/json"; 
      myRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), myRequest); 


     } 
    } 


    public void GetRequestStreamCallback(IAsyncResult callbackResult) 
    { 
     byte[] byteArray = null; 
     HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState; 

     // End the stream request operation 
     Stream postStream = myRequest.EndGetRequestStream(callbackResult); 

     // Create the post data 
     Dispatcher.BeginInvoke(() => 
     { 
      string mailToCheck = TxtBox_mail.Text.ToString(); 
      string postData = JsonConvert.SerializeObject(mailToCheck); 
      byteArray = Encoding.UTF8.GetBytes(postData); 
     }); 


     // Add the post data to the web request 
     postStream.Write(byteArray, 0, byteArray.Length); 
     postStream.Close(); 

     // Start the web request 
     myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallback), myRequest); 
    } 

나는 UI 스레드에 텍스트 상자 컨트롤의 값을 얻기 위해 디스패처를 사용했습니다하지만 BYTEARRAY 항상 입니다. 누군가 여기서 무엇이 잘못 될 수 있는지 알고 있습니까? 미리 감사드립니다.

+0

'byteArray = Encoding.UTF8.GetBytes (postData);'postData 란 무엇입니까? 기대하는 문자열이 포함되어 있습니까? 'Debug.WriteLine()'을 사용하여 값을 출력하십시오. – Sjips

답변

3

주된 문제점은 비동기식 BeginInvoke() 메서드를 사용 중이며 즉시 반환된다는 것입니다. 호출 된 대리자는 나중에 실행될 때까지 실행되지 않으므로 byteArray 변수는 현재 스레드가 데이터 쓰기를 시도 할 때 계속 null입니다.

해결 방법 중 하나는 Invoke() 방법을 대신 사용하는 것입니다. 이 방법은 동기식입니다. 즉, 호출 된 코드가 완료 될 때까지 리턴되지 않습니다.

IMHO, 더 좋은 방법은 비동기/대기 패턴을 사용하는 것입니다. 당신이 볼 수 있듯이, 코드의 주요 흐름은 일반, 직접적이고 순차적 인 방식으로 기록 될 수 있습니다 이런 식으로 일을

async void NextArrow_Tap(object sender, System.Windows.Input.GestureEventArgs e) 
{ 
    if (!String.IsNullOrEmpty(TxtBox_mail.Text)) 
    { 
     Uri myUri = new Uri("http://myUri"); 
     HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(myUri); 

     myRequest.Method = "POST"; 
     myRequest.ContentType = "application/json"; 

     Stream postStream = await myRequest.GetRequestStreamAsync(); 
     HttpWebResponse response = await GetRequestStreamCallback(postStream, myRequest); 

     // await GetResponsetStreamCallback(response) here...the 
     // method wasn't shown in the original question, so I've left 
     // out the particulars, as an exercise for the reader. :) 
    } 
} 


async void GetRequestStreamCallback(Stream postStream, WebRequest myRequest) 
{ 
    byte[] byteArray = null; 

    // Create the post data 
    string mailToCheck = TxtBox_mail.Text.ToString(); 
    string postData = JsonConvert.SerializeObject(mailToCheck); 
    byteArray = Encoding.UTF8.GetBytes(postData); 

    // Add the post data to the web request 
    postStream.Write(byteArray, 0, byteArray.Length); 
    postStream.Close(); 

    // Start the web request 
    return await myRequest.GetResponseAsync(); 
} 

어디 흐름을보고 그것을 더 쉽게, : 그것은 다음과 같이 보일 것입니다 의 실행은 로직 전체의 표현을 단순화하는 것이다.

+0

myRequest.GetResponseAsync() - 어떻게 작동 시키려고합니까? 그것은 정의되지 않을 것이다. –

+0

GetBytes는 스레드로부터 안전하지 않습니다. 대신 로컬 변수를 사용하는 것이 좋습니다. – demas

+0

@ChubosaurusSoftware : 올바른 ... 코드를 입력하기 위해 브라우저를 사용할 때의 위험 요소 중 하나입니다. :) 아직도, 나는 필요한 수정이 비교적 명백하다고 가정한다. 나는 그것을 알아낼 수없는 사람들을 위해 게시물에 추가했습니다. –

관련 문제