当以下服务被激活时,我得到以下异常(在同一个合同中不能有两个操作,同名,方法是ExecuteAsync和Execute)。
[ServiceContract]
public interface IMyService
{
[OperationContract]
byte[] Execute(MyRequest request);
[OperationContract]
Task<byte[]> ExecuteAsync(MyRequest request);
}
我想如果您使用svcutil.exe创建服务引用,这是有意义的,因为基于任务的操作是自动为您创建的。但是,我不想添加服务引用,而只是使用标准的ChannelFactory来创建WCF通道。如果不将异步方法重命名为其他方法,还有其他方法吗?或者我必须在Task.Run中将sync方法包装在客户端上吗?
答案 0 :(得分:11)
以上内容无效,因为WCF本身为您的案例Execute()
中的每个OperationContract创建了两个方法,一个同步和第二个异步,可以通过编写ServiceClientObj.ExexuteAsync(request)
在客户端调用,所以你不要&# 39;需要在IMyService
中明确添加异步方法。框架本身负责生成每个操作的async
方法
答案 1 :(得分:6)
这就是我的所作所为。我有两个单独的合同。一个用于客户端,一个用于服务器:
namespace ServiceLibrary.Server
{
[ServiceContract]
public interface IMyService
{
[OperationContract]
byte[] Execute(MyRequest request);
}
}
namespace ServiceLibrary.Client
{
[ServiceContract]
public interface IMyService : Server.IMyService
{
[OperationContract]
Task<byte[]> ExecuteAsync(MyRequest request);
}
}
因为两个ServiceContracts共享相同的名称,所以对于异步和同步方法,OperationContracts的Action和ReplyAction是相同的。客户端现在同时具有同步和异步版本,服务器保持不变。
答案 2 :(得分:5)
您可以声明其中之一,但不能同时声明两者。 WCF将自动使任一方法在生成的通道代理中工作 - 您可以将使用异步方法的接口连接到使用同步方法的实现,反之亦然。
如果你想在客户端和服务器代码之间共享接口定义(这不是不合理的)并且必须满足一个,你最好的选择是异步的:只提供同步意味着异步客户端必须浪费一个线程,同时提供只有async意味着调用者可以选择在必要时自行阻止和浪费线程。由于调用WCF服务涉及I / O,您肯定希望为客户端提供异步选项,即使服务器具有同步实现。
答案 3 :(得分:1)
异步方法是.NET构造。 Web服务标准不了解它们。 You do not need to do anything to enable clients to use async operations because server and client are independent.为客户端和服务器单独选择同步或异步。
由于这一事实常常导致难以置信,请让我说明以下内容:您可以拥有一个带异步客户端的同步服务器,反之亦然。
答案 4 :(得分:1)
尝试在OperationMethod中添加名称,以使其更简单。
[ServiceContract]
public interface IMyService
{
[OperationContract(Name = "Service1")]
byte[] Execute(MyRequest request);
[OperationContract(Name = "Service2")]
Task<byte[]> ExecuteAsync(MyRequest request);
}