0

我试图弄清楚如何在让其余代码运行之前确保事件已触发。

我连接了这样一个事件:

public static class ServiceUrlQueryParameters
{
      public static void ServiceUrlQueryParameters()
      {
          ... 
          dynamicMapServiceLayer.Initialized += new EventHandler<EventArgs>(DynamicMapServiceLayerQuery_Initialized); 
          ...
      }
}

所以现在,代码已经为事件附加了一个监听器,并将等到事件触发。但是我不希望该类中的其他任何事情发生,直到该事件触发,因为该地图服务层初始化会设置下一行代码所需的信息。不过,应用程序的其余部分和 GUI 中的代码应该继续运行。

我曾经在这样的事件处理侦听器方法中拥有其余代码。

private void DynamicMapServiceLayer_Initialized(object sender, System.EventArgs evArgs) 
{ 
   Query query = GetParameterQuery(); 
   QueryTask queryTask = new QueryTask(GetRestURL(dynMapServLayer));
   queryTask.ExecuteCompleted += GraphicQueryTask_ExecuteCompleted; 
   ... 
   queryTask.ExecuteAsync(query); 
} 

但这没有意义,因为执行查询在语义上与服务层的初始化无关。将查询代码放入在初始化地图图层时运行的事件处理程序方法对我来说似乎不合逻辑。所以,现在我有这样的:

public static class ServiceUrlQueryParameters
{
      public static void ServiceUrlQueryParameters()
      { 
          // No more Initialized event hookup to any event handling listener    
      }

    public static void QueryUrlParameters()
    {
        if ( ! dynMapServLayer.IsInitialized)
        {
            return; 
        }
        Query query = GetParameterQuery();
        QueryTask queryTask = new QueryTask(GetRestURL(dynMapServLayer));
        queryTask.ExecuteCompleted += GraphicQueryTask_ExecuteCompleted;
        queryTask.Failed += QueryTask_Failed;
        queryTask.ExecuteAsync(query);   
    }
}

但这不是一个好主意,因为当调用 QueryUrlParameters 时,Initialized 事件可能仍然没有触发(也许永远不会触发)。

4

2 回答 2

0

主要问题是执行查询在语义上与服务层的初始化无关,因此将查询放在层初始化事件的侦听器方法中是没有意义的。将查询代码放入在初始化地图图层时运行的事件处理程序方法中是不合逻辑的。

我还没有开始深入研究 .NET 4.5 任务并行库,所以我决定这样做。

在事件处理侦听器方法中,我像这样调用了查询方法。

private void DynamicMapServiceLayer_Initialized(object sender, System.EventArgs evArgs) 
{ 
   QueryUrlParameters();
} 

然后我将参数查询过程保存在一个名称与其职责相匹配的方法中:

public static void QueryUrlParameters()
{
   Query query = GetParameterQuery();
   QueryTask queryTask = new QueryTask(GetRestURL(dynMapServLayer));
   queryTask.ExecuteCompleted += GraphicQueryTask_ExecuteCompleted;
   queryTask.Failed += QueryTask_Failed;
   queryTask.ExecuteAsync(query);   
}

这仍然不是一个很好的解决方案。
我更喜欢等待事件初始化的更优雅的方式;但看起来这就是我现在所拥有的。

于 2013-05-22T13:51:14.360 回答
0

async/await 旨在解决您的特定问题。

您需要将 WCF 调用转换为任务。那么这是一个问题

public static async void QueryUrlParameters()
{
    await dynMapServLayer.EnsureIsInitialized();

    Query query = GetParameterQuery();
    QueryTask queryTask = new QueryTask(GetRestURL(dynMapServLayer));

    var result = await queryTask.ExecuteAsync(query);   

    // etc ....
}

更新:

On VS2010, you can either using Async CTP or use this syntax http://msdn.microsoft.com/en-us/vstudio/hh533273.aspx 

   initializationTask.ContinueWith(()=> ...)

It is best to try this with a test project first.
于 2013-05-21T03:22:28.337 回答