2015-10-15 245 views
2

我必須從WCF服務中調用三種不同的異步方法。我有以下方法,其中包括所有三個調用:等待多個異步調用完成?

private async Task CreateMultipleTasksAsync() 
{ 
    CrimcaseServiceClient client = new CrimcaseServiceClient(
     new BasicHttpBinding(), 
     new EndpointAddress("http://192.168.1.100/FooService/FooService.svc") 
     ); 

    client.GetEventCompleted += OnGotEventResult; 
    client.GetEventAsync(eventInfo); 

    client.GetLocationsCompleted += OnGotLocationsResult; 
    client.GetLocationsAsync(); 

    client.GetTypesCompleted += OnGotTypesResult; 
    client.GetTypesAsync(); 
} 

在所有三個調用完成後,我需要填充一些值。但是,我似乎遇到了如何等待所有三人首先完成的問題。

我已經試過這樣做,使用這種電話,但它仍然不是等待所有的呼叫纔去到下一個代碼位來完成:

private void GrabData() 
{ 
    var task = Task.Run(async() => { await CreateMultipleTasksAsync(); }); 
    task.Wait(); 
} 

任何建議將不勝讚賞,因爲我迷失在這個時候做什麼。

謝謝大家。

+1

什麼是你異步調用的方法簽名?另外,你說:*但它仍然在等待所有的調用完成,然後再進入下一個代碼*不是你想要的嗎? –

+0

這是一個錯字 - 對不起。我的意思是說,在進入下一個代碼之前,它不是等待所有的調用完成。在查看生成的呼叫時,它們都被設置爲無效。 (我希望我正確理解你的問題) – BrewingDev

+0

我假設方法簽名是爲異步方法是'無效'返回? –

回答

7

從WCF服務

我建議你重建你的WCF客戶端代理,並啓用異步調用。目前,它使用的是an older pattern,但如果使用現代Visual Studio版本進行重新生成,則應生成newer pattern,與async/await的效果更好。

然後你就可以實際使用await與WCF直接調用:

private async Task CreateMultipleTasksAsync() 
{ 
    CrimcaseServiceClient client = new CrimcaseServiceClient(
    new BasicHttpBinding(), 
    new EndpointAddress("http://192.168.1.100/FooService/FooService.svc") 
    ); 

    // Start the three asynchronous calls. 
    var getEventTask = client.GetEventAsync(eventInfo); 
    var getLocationsTask = client.GetLocationsAsync(); 
    var getTypesTask = client.GetTypesAsync(); 

    // Asynchronously wait (await) for them all to complete. 
    await Task.WhenAll(getEventTask, getLocationsTask, getTypesTask); 

    // Retrieve the results of the calls. 
    var event = await getEventTask; 
    var locations = await getLocationsTask; 
    var types = await getTypesTask; 

    // TODO: place OnGotEventResult/OnGotLocationsResult/OnGotTypesResult logic here 
} 

你打電話時,你應該只是一個await這樣做,不使用Task.RunTask.Wait

await CreateMultipleTasksAsync(); 
// At this point, the results have been retrieved and processed. 
+0

Stephen Clearly - 非常感謝你的細節回覆。我一直在使用SvcUtil來生成代理。所以,我刪除了生成的文件,並直接通過VS將服務引用添加到我的項目中,但是我得到了「無法將類型'void'隱式轉換爲'System.Threading.Tasks.Task'。一個Xamarin PCL應用程序,我只是創建代理完全錯誤? – BrewingDev

+1

@SUCODev:我懷疑這是Xamarin應用程序拋出它。嘗試創建一個普通的PCL或.NET 4.5 dll並生成服務引用。 –