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

时间:2015-02-19 17:31:33

标签: c# wcf .net-4.5

当以下服务被激活时,我得到以下异常(在同一个合同中不能有两个操作,同名,方法是ExecuteAsync和Execute)。

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

        [OperationContract]
        Task<byte[]> ExecuteAsync(MyRequest request);
    }

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

5 个答案:

答案 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);
}