0

我有一个 silverlight 5 应用程序,它依赖于对 Web 服务的多个异步调用来填充新创建的图形的属性。我正在尝试找到一种方法来同步处理这些异步调用。我已经尝试了这篇文章这篇文章中列出的建议。我已经尝试了许多关于 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 本质上是异步的,因此强迫它尝试同步工作通常是一个非常糟糕的主意。除非绝对必要,否则您不应该这样做。

有没有理由你不能等待异步。打回来?从我看到的情况来看,您似乎对正在呈现的每个状态都进行了两次调用。我猜担心的是必须在拨打第二个电话之前完成一个电话?在这样的场景中,我会启动第一个异步调用,并在它的响应中启动第二个调用,传递您希望从第一个调用中使用的结果。第二个调用响应更新提供的引用。

但是,如果您有大量的状态要更新,这会导致相当冗长且难以调试的调用集。我真的在考虑创建一个服务调用,它可以接受一组状态引用并传回一个数据结构集,以便一次更新所有值。(或者如果批处理太耗时并且您希望在加载视觉元素时对其进行渲染/交互,则至少将它们分组为每个状态一次调用。)

于 2012-07-30T02:35:20.620 回答