0

新しく作成されたグラフィックの属性を設定するために、Webサービスへのいくつかの非同期呼び出しに依存するSilverlight5アプリがあります。これらの非同期呼び出しを同期的に処理する方法を見つけようとしています。私はこの記事これにリストされている提案を試しました。Dispatcherオブジェクトに関する多くの提案を試しました。うまく機能したものはないので、明らかに何かが欠けています...

これが私が持っているものです:

public partial class MainPage : UserControl {

 AutoResetEvent waitHandle = new AutoResetEvent(false);

 private void AssignNewAttributeValuesToSplitPolygons(List<Graphic> splitGraphics)
 {
   for (int i = 0; i < splitGraphics.Count; i++) 
   {
       Graphic g = splitGraphics[i];

       Thread lookupThread1 = new Thread(new ParameterizedThreadStart(SetStateCountyUtm));
       lookupThread1.Start(g);
       waitHandle.WaitOne();

       Thread lookupThread2 = new Thread(new ParameterizedThreadStart(SetCongressionalDistrict));
       lookupThread1.Start(g);
       waitHandle.WaitOne();
 }

 private void SetStateCountyUtm(object  graphic)
 {
    this.Dispatcher.BeginInvoke(delegate() {
            WrapperSetStateCountyUtm((Graphic)graphic);
     });
 }

 private void WrapperSetStateCountyUtm(Graphic graphic)
    {
        GISQueryEngine gisQEngine = new GISQueryEngine();
        gisQEngine.StateCountyUtmLookupCompletedEvent += new GISQueryEngine.StateCountyUtmLookupEventHandler(gisQEngine_StateCountyUtmLookupCompletedEvent);
        gisQEngine.PerformStateCountyUtmQuery(graphic.Geometry, graphic.Attributes["clu_number"].ToString());
    }

 void gisQEngine_StateCountyUtmLookupCompletedEvent(object sender, StateCountyUtmLookupCompleted stateCountyUtmLookupEventArgs)
 {
     string fred = stateCountyUtmLookupEventArgs.
     waitHandle.Set();
 }     

}

public class GISQueryEngine
{
  public void PerformStateCountyUtmQuery(Geometry inSpatialQueryGeometry, string cluNumber)
    {
        QueryTask queryTask = new QueryTask(stateandCountyServiceURL);
        queryTask.ExecuteCompleted += new EventHandler<QueryEventArgs>(queryTask_StateCountyLookupExecuteCompleted);
        queryTask.Failed += new EventHandler<TaskFailedEventArgs>(queryTask_StateCountyLookupFailed);
        Query spatialQueryParam = new ESRI.ArcGIS.Client.Tasks.Query();
        spatialQueryParam.OutFields.AddRange(new string[] { "*" });
        spatialQueryParam.ReturnGeometry = false;

        spatialQueryParam.Geometry = inSpatialQueryGeometry;
        spatialQueryParam.SpatialRelationship = SpatialRelationship.esriSpatialRelIntersects;
        spatialQueryParam.OutSpatialReference = inSpatialQueryGeometry.SpatialReference;

        queryTask.ExecuteAsync(spatialQueryParam, cluNumber);
    }

  //and a whole bunch of other stuff i can add if needed
}

'waitHandle.WaitOne()'メソッドのコメントを外したままにすると、そのメソッド以外のコードは呼び出されません。少なくとも、デバッガーのステップスルーで確認できます。アプリケーションがハングするだけです。

'waitHandle.WaitOne()'をコメントアウトすると、非同期を除いてすべてが正常に実行されます。つまり、アプリが新しいグラフィックの属性値を読み取るときに、非同期メソッドが返される速度に応じて、これらの値が設定される場合と設定されない場合があります。

助けてくれてありがとう。

4

1 に答える 1

2

対処する必要がある問題がいくつかあるため、このような問題を解決するのはかなり困難です。SL は本質的に非同期であるため、強制的に同期的に動作させることは通常、非常に悪い考えです。絶対に必要でない限り、それを行うべきではありません。

非同期を待つことができない理由はありますか。折り返し電話?私が見たところ、レンダリングされているすべての状態に対して 2 つの呼び出しを行っているようです。2番目の呼び出しが行われる前に、1つの呼び出しが完了しなければならないという懸念があると思いますか? このようなシナリオでは、最初の非同期呼び出しを開始し、その応答で、最初の呼び出しから使用する結果を渡す 2 番目の呼び出しを開始します。2 番目の呼び出し応答は、提供された参照を更新します。

ただし、更新する状態が多数ある場合は、かなりおしゃべりになり、一連の呼び出しをデバッグするのが難しくなります。私は、状態参照のセットを受け入れ、値がすべて 1 回のヒットで更新されるように設定されたデータ構造を返すことができるサービス呼び出しの作成を実際に検討しています。(または、バッチに時間がかかりすぎて、読み込み時にビジュアル要素をレンダリング/操作したい場合は、少なくとも状態ごとに 1 つの呼び出しにグループ化します。)

于 2012-07-30T02:35:20.620 に答える