在同一个具有相同名称的合同中不能有两个操作(Async和Non)

当激活以下服务时,我得到以下exception(在相同的合同中不能有两个操作,具有相同的名称,方法ExecuteAsync和Execute)。

[ServiceContract] public interface IMyService { [OperationContract] byte[] Execute(MyRequest request); [OperationContract] Task ExecuteAsync(MyRequest request); } 

我想如果您使用svcutil.exe来创建服务引用,这是有道理的,因为基于任务的操作是自动为您创建的。 但是,我不想添加服务引用,而只是使用标准的ChannelFactory来创建WCF通道。 如果不将异步方法重命名为其他方法,还有其他方法吗? 或者我必须在Task.Run中的客户端上包装sync方法吗?

以上是无效的,因为WCF本身为您的每个OperationContract创建两个方法Execute()一个同步和第二个异步,可以通过编写ServiceClientObj.ExexuteAsync(request)在客户端调用,因此您不需要添加IMyService显式的异步方法。框架本身负责生成每个操作的async方法

这就是我做的。 我有两个单独的合同。 一个用于客户端,一个用于服务器:

 namespace ServiceLibrary.Server { [ServiceContract] public interface IMyService { [OperationContract] byte[] Execute(MyRequest request); } } namespace ServiceLibrary.Client { [ServiceContract] public interface IMyService : Server.IMyService { [OperationContract] Task ExecuteAsync(MyRequest request); } } 

由于两个ServiceContracts共享相同的名称,因此对于异步和同步方法,OperationContracts的Action和ReplyAction是相同的。 客户端现在同时具有同步和异步版本,服务器保持不变。

您可以声明其中之一,但不能同时声明。 WCF将自动使任一方法在生成的通道代理中工作 – 您可以将使用异步方法的接口连接到使用同步方法的实现,反之亦然。

如果你想在客户端和服务器代码之间共享接口定义(这不是不合理的)并且必须满足一个,你最好的选择是异步的:只提供同步意味着异步客户端必须浪费一个线程,同时只提供异步手段如果必须,呼叫者可以选择阻止和浪费线程。 由于调用WCF服务涉及I / O,您肯定希望为客户端提供异步选项,即使服务器具有同步实现。

异步方法是.NET构造。 Web服务标准不了解它们。 您无需执行任何操作即可使客户端使用异步操作,因为服务器和客户端是独立的。 为客户端和服务器单独选择同步或异步。

由于这个事实经常导致难以置信,让我说明以下内容:您可以拥有一个带异步客户端的同步服务器,反之亦然。

尝试在OperationMethod中添加名称以使其更简单。

 [ServiceContract] public interface IMyService { [OperationContract(Name = "Service1")] byte[] Execute(MyRequest request); [OperationContract(Name = "Service2")] Task ExecuteAsync(MyRequest request); }