我需要将第三方的Web API方法集成到WCF服务中。 WCF服务将由另一个外部方呼叫,他们希望呼叫和返回是同步的。
我可以使用通常的RestClient.ExecuteAsync
来获取API的结果。
我将以下内容放在同步调用中:
public static List<Books> GetSyncBooks(int companyId)
{
var response = GetSynchronousBooks(companyId);
var content = response.Result.Content;
List<Books> result = new List<Books>();
return Helpers.JSONSerialiser.Deserialize<BookList>(content);
}
async private static Task<IRestResponse> GetSynchronousBooks(int companyId)
{
var request = BuildGETRequest("Book", companyId);
var response = await RestSharpHelper.ExecuteSynchronousRequest(request);
return response;
}
public static Task<IRestResponse> ExecuteSynchronousRequest(RestRequest request)
{
var client = new RestClient(BaseUrl);
client.AddHandler("application/json", new RestSharpJsonDotNetDeserializers());
var tcs = new TaskCompletionSource<IRestResponse>(TaskCreationOptions.AttachedToParent);
client.ExecuteAsync(request, (restResponse, asyncHandle) =>
{
if (restResponse.ResponseStatus == ResponseStatus.Error)
tcs.SetException(restResponse.ErrorException);
else
tcs.SetResult(restResponse);
});
return tcs.Task;
// BREAKPOINT here shows TASK value as
// Id = 1, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}"
}
但问题是,我从来没有得到过这样的结果。响应内容始终为null。我做错了什么?
编辑:谢谢斯蒂芬。我已经在这个问题的一些问题上看到了你的名字:你的分数似乎表明你知道你的方式。我确实根据您在另一个问题上的回答指示了wcf服务调用。我可以问你一个相关的后续问题吗?如此示例的异步WCF服务调用的可伸缩性如何?对于每秒10到100范围内的多个同时呼叫,它是否“正常工作”,忽略了下游的处理开销?答案 0 :(得分:4)
我假设您的WCF服务托管在ASP.NET中。
您的问题在于:response.Result
。我在博客上解释this deadlock situation。总之,await
将捕获当前&#34;上下文&#34; (在这种情况下,是一个ASP.NET请求上下文),并将使用它来恢复async
方法。但是,ASP.NET请求上下文一次只允许一个线程,因此如果请求线程被阻塞(调用response.Result
),那么async
方法永远不会继续,并且会出现死锁。 / p>
解决方案是纠正这种误解:
WCF服务将由另一个外部方呼叫,他们希望呼叫和返回是同步的。
由于您正在处理客户端/服务器方案,因此您不必使其同步。客户端的异步完全独立于服务器的异步。
因此,只需异步实现您的WCF服务:
public static Task<List<Books>> GetBooksAsync(int companyId)
{
var response = await GetBooksAsync(companyId);
var content = response.Content;
List<Books> result = new List<Books>();
return Helpers.JSONSerialiser.Deserialize<BookList>(content);
}
如果客户希望,客户端仍然可以同步调用它。