C# 如何在Silverlight中同步调用异步服务

C# 如何在Silverlight中同步调用异步服务,c#,multithreading,silverlight,asynchronous,C#,Multithreading,Silverlight,Asynchronous,我有一个silverlight 5应用程序,它依赖于对web服务的几个异步调用来填充新创建的图形的属性。我试图找到一种同步处理这些异步调用的方法。我已经尝试了本文和中列出的建议。我尝试了许多关于Dispatcher对象的建议。没有一个能很好地工作,所以我显然错过了一些东西 以下是我所拥有的: public partial class MainPage : UserControl { AutoResetEvent waitHandle = new AutoResetEvent(false);

我有一个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
}
public部分类主页面:UserControl{
AutoResetEvent waitHandle=新的AutoResetEvent(假);
私有void AssignNewAttributeValuesToSplitPolygons(列表splitGraphics)
{
对于(int i=0;i
如果我不注释'waitHandle.WaitOne()'方法,则不会调用该方法之外的任何代码,至少我可以通过分步调试看到这一点。应用程序只是挂起

如果我注释掉“waitHandle.WaitOne()”,则所有操作都可以正常运行—异步除外。换句话说,当应用程序读取新图形的属性值时,这些值可以设置,也可以不设置,这取决于异步方法返回的速度


感谢您的帮助。

解决这样的问题会非常困难,因为您需要解决一些问题。SL本质上是异步的,因此强制它尝试同步工作通常是一个非常糟糕的主意。除非绝对必要,否则不应该这样做

您不能等待async.callback有什么原因吗?据我所知,您似乎对呈现的每个状态都进行了两次调用。我猜问题是一次调用必须在第二次调用之前完成?在这种情况下,我将启动第一次异步调用,并在其响应中启动第二次调用p根据第一次调用的结果进行搜索。第二次调用响应更新提供的引用


但是,如果有大量状态需要更新,这会导致调用集变得非常健谈且难以调试。我将真正考虑创建一个服务调用,该调用可以接受一组状态引用,并为要更新的值一次性传回一个数据结构集。(或者,如果批处理过于耗时,并且您希望在加载视觉元素时渲染/与视觉元素交互,则至少将它们分组为每个状态一次调用。)

谢谢你的回答。每个图形都是用户创建的多边形,因此每个州没有一个图形。我只需要知道用户绘制多边形的州、县等。我希望它们同步,因此我确定在尝试使用它们之前设置了属性值。我想我可以将所有异步调用链接在一起,placi正在取消当前callbacsk中的下一个调用。这似乎不太“令人满意”。通常在这样的场景中,交互元素的对象状态(图)将由在其视图模型中设置的属性控制。上下文菜单等内容在视图模型报告所有属性都不可用之前不会启用。这可能需要一些工作,但在用户加载时为其提供可用项的灵活性(而不是等待整件事)非常有价值。我最终将事件处理程序链接在一起-每个处理程序调用下一个异步方法。这有点难看,但似乎工作得很好。再次感谢您的帮助。您看过关于使用Caliburn.Micro的内容吗?我以前没有见过。谢谢您的提示。