2011-07-06 7 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

あなたが持っている問題は(私はそのための正しい用語を忘れる)非GUIスレッドがUI要素を変更しようとしていることもracing conditionの組み合わせである、と。

WPFでは、Dispatcherパターンを使用して2番目の問題を解決します。 Winformsでは、InvokeRequiredパターンを使用します。レースの条件を戦うために...「ロード...」または「フェッチ...」またはその効果に何かにNameTextBlock.Textを設定

_fbClient.GetAsync("/me"); 

を呼び出す前に

。このようにして、非同期呼び出しが完了すると、テキストボックスに正しい詳細を入力できます。また、スタイリングを変更して、ユーザーにとってよりわかりやすくすることもできます(読み込み時には灰色、結果があれば明るい赤色)。あなたが今やっていることは、テキストボックスのテキストをname変数に設定するときに、イベント(非同期呼び出し)がすでに完了していることを前提としています。これは実際の場合とそうでない場合があります!

もっと単純な方法でそれを想像してください。ガレージの二人。あなたはガレージのドアを開けるために1つを送り、もう1つは車庫にバンを運ぶために送る。あなたの現在のコードでは、バンを運転している人は、ガレージのドアがまだ開いているかどうかをチェックしたり、気をつけたりすることなくガレージに運転しています。

次の問題はThread Safetyです。 "name"変数は同時に読み書きすることができます。つまり、読み込み操作は揮発性メモリ上で動作することができ、特に大きなスケールでエラー/問題が発生する可能性があります。

もっと良いアイデアを得るには、Thread Synchronizationをご覧ください。

そこに消化する情報がたくさんあります。それが助けてもらいたい!

+0

誰かが正しい用語が間違ったスレッドからUI要素をくださいアクセスしようとするためであるものを私に思い出させることはできますか?私はそれで眠りを失うだろう! ^^ – Smudge202

0

あなたが提供したコードスニペットで回答があります。
はそうのようなDispatcher.BeginInvokeメソッドを使用します。

Dispatcher.BeginInvoke(() => NameTextBlock.Text = "[" + name + "]");