WCF异步调用导致死锁?

问题描述 投票:0回答:2

我有一个 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
不支持异步调用?

c# wcf async-await
2个回答
0
投票

我认为你的最后一个问题是可能的,因为我在测试客户端上看到以下错误。

enter image description here

最终我改了客户端代码,没有改服务代码。目前运作良好。

 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();

enter image description here


0
投票

经过多次尝试,我发现罪魁祸首就是渠道。看来 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();
© www.soinside.com 2019 - 2024. All rights reserved.