我有一个 WCF 合约,其中包含一个同步方法和一个异步方法,其定义和实现如下:
[ServiceContract]
public interface IFooService
{
[OperationContract]
string GetFoo(int value);
[OperationContract]
Task<string> GetBarAsync();
}
public class FooService : IFooService
{
public string GetFoo(int value)
{
return value.ToString();
}
public Task<string> GetBarAsync()
{
return Task.Run(() =>
{
Task.Delay(6000).Wait();
return "done!";
});
}
}
在客户端,我有一个控制台程序:
class Program
{
public static async Task Main(string[] args)
{
NetNamedPipeBinding binding = new NetNamedPipeBinding();
var proxy = new ChannelFactory<IFooService>(binding, new EndpointAddress("net.pipe://localhost/Test")).CreateChannel();
Console.WriteLine("GetFoo result: " + proxy.GetFoo(1));
var tmp = await proxy.GetBarAsync();
Console.WriteLine("GetBarAsync result: " + tmp);
Console.WriteLine("GetFoo result: " + proxy.GetFoo(2));
Console.ReadLine();
}
}
输出
GetFoo result: 1
,等待6秒后输出GetBarAsync result: done!
,至此一切都在意料之中。然而,它只是挂在那里,从不输出最后一行,即GetFoo result: 2
。
有人可以帮忙解释一下原因吗?难道是死锁了?或者 WCF
Channel
不支持异步调用?
我认为你的最后一个问题是可能的,因为我在测试客户端上看到以下错误。
最终我改了客户端代码,没有改服务代码。目前运作良好。
Console.WriteLine("GetFoo result: " + proxy.GetFoo(1));
var tmp =proxy.GetBar();
Console.WriteLine("GetBarAsync result: " + tmp);
Console.WriteLine("GetFoo result: " + proxy.GetFoo(2));
var tmp1 = proxy.GetBar();
Console.WriteLine("GetBarAsync result: " + tmp1);
Console.ReadLine();
经过多次尝试,我发现罪魁祸首就是渠道。看来 WCF 通道是一次性用于异步调用的。如果我创建一个新通道,第二个同步调用将按预期返回。
Console.WriteLine("GetFoo result: " + proxy.GetFoo(1));
var tmp = await proxy.GetBarAsync();
Console.WriteLine("GetBarAsync result: " + tmp);
****** recreate channel solve the problem ******
proxy = new ChannelFactory<IFooService>(binding, new EndpointAddress("net.pipe://localhost/Test")).CreateChannel();
************************************************
Console.WriteLine("GetFoo result: " + proxy.GetFoo(2));
Console.ReadLine();