How to wait until an event is finished without blocking execution in the UI

一曲冷凌霜 提交于 2019-12-20 06:27:50

问题


I’m trying to figure out how can I make sure that the event has fired before letting the rest of the code run.

I hook up an event like this:

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

So now, the code has attached a listener to the event and will wait until the event fires. But I don't want anything else in that class to happen until that event has fired because that map service layer initialization brings sets up the info that the next lines of code need. The code in the rest of the application and the GUI should continue to run, though.

I used to have the rest of the code in the event handling listener method like this.

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

But that doesn't make sense because executing a query is not semantically related to a service layer getting initialized. Putting query code in an event handler method that runs when a map layer is initialized doesn’t seem t logical to me. So, now I have it like this:

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

But that is not such a great idea because when the QueryUrlParameters is called, the Initialized event still might not have fired (and maybe it never will).


回答1:


The async/await is designed to solve your particular set of problems.

You'll need to turn the WCF calls into Tasks. Then it is a matter of

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

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

    var result = await queryTask.ExecuteAsync(query);   

    // etc ....
}

Update:

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.



回答2:


The main problem was that executing a query is not semantically related to a service layer getting initialized and so it didn't make sense to put the query in the layer initialization event's listener method. Putting query code in an event handler method that runs when a map layer is initialized isn't logical.

I haven't yet started on examining the .NET 4.5 Task Parrallel library in any serious depth, so I've decided to do this.

In the event handling listener method, I made a call to the query method like this.

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

And then I keep the parameter querying procedure in a method that has a name that matches its responsibility:

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

This is still not such a great solution.
I would have preferred a more elegant way of waiting for the event to have initialized; but it looks like this is all I've got for now.



来源:https://stackoverflow.com/questions/16659582/how-to-wait-until-an-event-is-finished-without-blocking-execution-in-the-ui

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!