簡體   English   中英

使用異步任務調用同步WCF服務

[英]Using asynchronous tasks to call synchronous WCF service

我有一個WCF服務,由服務客戶端調用。 我想使用async / await結構來包裝對此的調用; 但是,服務和服務客戶​​端是.NET3.5。 我對此的解決方案如下:

private async Task<ObservableCollection<MyEntity>> LoadData(ParamData param)
{
        ServiceClient svc = new ServiceClient();
        int results = 0;

        // Set-up parameters
        myParams = BuildParams(param);

        // Call a count function to see how much data we're talking about
        // This call should be relatively quick
        var counter = Task.Factory.StartNew(() =>
        {
            results = svc.GetResultCount(myParams);
        }).ContinueWith((task) =>
        {
            if (results <= 10000 ||
                (MessageBox.Show("More than 10000 results, still retrieve data?"), MessageBoxButton.YesNo) == MessageBoxResult .Yes))
            {
                return svc.Search(myParams);
            }
        });
}

我收到編譯錯誤:

Since 'System.Action<System.Threading.Tasks.Task>' returns void, a return keyword must not be followed by an object expression

因此,我的問題是,是否可以以此方式運行同步方法?如果是,我在做什么錯? 我的目標是可以像這樣調用該方法:

var data = await LoadData(params);

添加服務參考時,有一個選項可以生成操作的異步版本。

這是(較舊的)APM模式(IAsyncResult,BeginMethod,EndMethod)。 您可以使用FromAsync將其掛接到異步/等待中:

 var task = Task.Factory.FromAsync(BeginGetResultCount, EndGetResultCount, myParams);

當您有許多調用時,這會更好,它不會浪費太多線程來等待I / O。

在您的問題中,您首先要聲明您的客戶端在.NET 3.5上,但隨后您要使用async方法並標記您的問題.NET 4.5。 因此,我假設您實際上是在.NET 4.5上運行。

在這種情況下,您可以告訴svcutil創建基於任務的異步API(在VS2012中,默認情況下應該這樣做),然后像這樣調用它們:

private async Task<ObservableCollection<MyEntity>> LoadData(ParamData param)
{
    ServiceClient svc = new ServiceClient();

    // Set-up parameters
    myParams = BuildParams(param);

    // Call a count function to see how much data we're talking about
    // This call should be relatively quick
    var results = await svc.GetResultCountAsync(myParams);
    if (results <= 10000 ||
        (MessageBox.Show("More than 10000 results, still retrieve data?"), MessageBoxButton.YesNo) == MessageBoxResult .Yes))
        return await svc.Search(myParams);
}

如果你實際上在.NET 4.0,然后亨克具有正確的答案。 在這種情況下,您可能會發現我的async WCF博客文章很有幫助。

好的-我已經解決了。 return語句從任務而不是函數返回; 這就是為什么它抱怨。

正確的代碼如下所示:

private async Task<ObservableCollection<MyEntity>> LoadData(ParamData param)
{
    ServiceClient svc = new ServiceClient();
    int results = 0;

    // Set-up parameters
    myParams = BuildParams(param);

    // Call a count function to see how much data we're talking about
    // This call should be relatively quick
    var counter = Task.Factory.StartNew(() =>
    {
        results = svc.GetResultCount(myParams);
    });

    var returnTask = counter.ContinueWith((task) =>
    {
        if (results <= 10000 ||
            (MessageBox.Show("More than 10000 results, still retrieve data?"), MessageBoxButton.YesNo) == MessageBoxResult .Yes))
        {
            return svc.Search(myParams);
        }
    });

    return returnTask.Result;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM