2013-05-20 23 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) –

相關問題