2013-05-20 24 views
0

我想弄清楚如何确保该事件在让其余的代码运行之前触发。如何等待,直到一个事件完成,而不阻止在UI中执行

我挂钩的事件是这样的:

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被调用时,初始化事件仍可能没有解雇(也许它永远不会)。

+0

代码不**在UI中随机运行。如果你不想做某件事,因为你的程序没有准备好,那么让用户明白。 *永远不要*只是忽略一个请求,对于一个用户无奈地敲打鼠标按钮而言,没有什么好看的。禁用输入,显示一个漂亮的图片。 –

回答

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. 
+0

.NET 4.5是否使用?我有Visual Studio 2010和.NET 4.0。 – Beebok

+0

其实,我没有使用WCF。它使用REST服务。 – Beebok

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); 
} 

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

+0

如果要隐藏服务层到客户端的初始化,那么它应该是服务层执行查询的角色。例如serviceLayer.ExecuteQueryAsync(queryTask) –

相关问题