2011-07-06 112 views
0

我很欣賞GetAsync是,異步,但我找不到任何文檔如何使用它。在這個階段,我想要的只是獲取我的名字並將其分配給文本塊。當然,如果我在_fbClient.GetCompleted + =/_fbClient.GetAsync(「/ me」)塊中這樣做,它會得到無效的跨線程訪問異常錯誤。新手:無效的跨線程訪問使用GetAsync

在下面的代碼中,NameTextBlock控件當然設置爲「[EMPTY]」,並在一段時間後標記爲=======>的行被執行,導致錯誤。

我見過的幾個例子使用了似乎是同步的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爲「載入中...」或「取...」或諸如此類的話之前打擊的賽車狀況......。這樣,當異步調用完成時,它可以用正確的細節填充文本框。您可能還想更改樣式以使其對用戶更加明顯(如加載時爲灰色,當您獲得結果時爲鮮紅色)。你現在正在做的是假設當你將文本框的文本設置爲name變量時,事件(異步調用)已經完成。這可能或可能不是這樣!

想象一下更簡單的方法。兩個人在一個車庫。你發送一個打開車庫門,另一個將車開進車庫。在你現在的代碼中,駕駛這輛貨車的那個人正在開車進入車庫,不檢查或關心車庫門是否打開。

下一個問題是Thread Safety。可以同時讀取和分配「名稱」變量,這意味着讀取操作可以在易失性存儲器上運行,並且很可能導致錯誤/問題 - 特別是在較大規模上!

我建議你看看Thread Synchronization以獲得更好的想法。

很多信息在那裏消化,抱歉。希望它有幫助,但!

+0

可有人提醒我,正確的說法是什麼,試圖從錯誤的線程訪問UI元素嗎?我會失去它的睡眠! ^^ – Smudge202

0

你在你提供的代碼片段中有答案。
使用Dispatcher.BeginInvoke方法,像這樣:

Dispatcher.BeginInvoke(() => NameTextBlock.Text = "[" + name + "]"); 
相關問題