[英]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.