如何等待事件完成而不阻止UI中的执行

时间:2013-05-20 22:49:37

标签: .net silverlight

我正在试图弄清楚如何在让剩下的代码运行之前确保事件已经触发。

我挂了这样一个事件:

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事件仍然可能没有被触发(也许它永远不会)。

2 个答案:

答案 0 :(得分:0)

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

您需要将WCF调用转换为Tasks。那就是

的问题
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.

答案 1 :(得分: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);   
}

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