2011-07-06 9 views
0

GetAsync는 비동기식이지만 잘 사용하는 방법에 대한 설명서는 찾을 수 없습니다. 이 단계에서 원하는 것은 내 이름을 가져 와서 텍스트 블록에 할당하는 것뿐입니다. 물론 _fbClient.GetCompleted + =/_fbClient.GetAsync ("/ me") 블록 내에서이 작업을 수행하면 잘못된 크로스 스레드 액세스 예외 오류가 발생합니다.초보자 : GetAsync를 사용하는 크로스 스레드 액세스가 잘못되었습니다.

아래 코드에서 NameTextBlock 컨트롤은 물론 "[비어 있음]"으로 설정되고 나중에 =======> 표시된 줄이 실행되어 오류가 발생합니다.

필자가 본 몇몇 예제는 동기식 Get 메서드로 보이지만 사용하지 않은 것처럼 보입니다 (어쨌든 사용하고 싶지는 않습니다).

string name = "EMPTY"; 
     try 
     { 
      _fbClient.GetCompleted += 
      (o, e) => 
      { 
       if (e.Error == null) 
       { 
        var result = (IDictionary<string, object>)e.GetResultData(); 
        //Dispatcher.BeginInvoke(() => MyData.ItemsSource = result); 
        var tempname = (string)result["name"]; 
        name = (string)result["name"]; 
        NameTextBlock.Text = "[" + name + "]"; 
       } 
       else 
       { 
        MessageBox.Show(e.Error.Message); 
       } 
      }; 

      _fbClient.GetAsync("/me"); 
//======>  NameTextBlock.Text = "[" + name + "]"; 


     } 
     catch 
     { 
      MessageBox.Show("Failed.. deal with issues."); 
     } 
     finally 
     { 
      NameTextBlock.Text = "[" + name + "]"; 
     } 

답변

1

당신이 가진 문제는 racing condition의 조합이며, 비 GUI 스레드가 UI 요소를 변경하려고 또한 (그에 대한 올바른 용어를 잊지).

WPF에서는 Dispatcher 패턴을 사용하여 두 번째 문제를 해결합니다. Winforms에서는 InvokeRequired 패턴을 사용합니다.

_fbClient.GetAsync("/me"); 

가 NameTextBlock.Text 그 효과에 "로드 ..."또는 "가져 오는 중 ..."또는 뭔가를 설정 호출하기 전에 경주 조건을 ... 방지합니다. 비동기 호출이 완료되면 텍스트 상자에 올바른 세부 정보를 입력 할 수 있습니다. 스타일을 변경하여 사용자가 더 분명하게 보이도록 할 수 있습니다 (예 :로드 할 때 회색, 결과가있을 때 밝은 빨간색). 지금 당장 당신이하고있는 일은 textbox의 텍스트를 name 변수로 설정하면 이벤트 (비동기 호출)가 이미 완료되었다고 가정하는 것입니다. 이것은 사실 일 수도 있고 아닐 수도 있습니다!

좀 더 단순한 방법으로 상상해보십시오. 차고에 두 사람. 차고 문을 열려면 하나를 보내고 차고에 밴을 보내려면 다른 사람을 보내십시오. 현재 코드에서 밴을 운전하는 사람은 차고 문이 열려 있는지 여부를 확인하거나 신경 쓰지 않고 차고로 운전하고 있습니다.

다음 문제는 Thread Safety입니다. "이름"변수는 동시에 읽고 쓸 수 있습니다. 즉, 읽기 작업이 휘발성 메모리에서 작동 할 수 있으며 특히 큰 스케일에서는 오류/문제가 발생할 수 있습니다!

더 좋은 아이디어를 얻으려면 Thread Synchronization을 살펴 보시기 바랍니다.

거기서 소화 할 정보가 많습니다. 죄송합니다. 그것이 비록 도움이되기를 바란다!

+0

사람이 올바른 용어가 잘못된 스레드에서 UI 요소를하시기 바랍니다에 액세스하려고에 대해 무엇을 생각 나게 할 수 있나요? 나는 그것에 잠을 잃을거야! ^^ – Smudge202

0

제공하신 코드 스 니펫에 답변 해 주셨습니다.
그래서 같은 Dispatcher.BeginInvoke 방법을 사용

Dispatcher.BeginInvoke(() => NameTextBlock.Text = "[" + name + "]"); 
관련 문제