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