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

Bre*_*ner 17 c# wcf .net-4.5

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

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

        [OperationContract]
        Task<byte[]> ExecuteAsync(MyRequest request);
    }
Run Code Online (Sandbox Code Playgroud)

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

Ehs*_*jad 11

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

  • 如果使用`ChannelFactory`,则不会自动生成异步方法. (6认同)

Bre*_*ner 7

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • @Gouda 我将不得不不同意你的观点。尽管 Jeroen 和 Ehsan 提供了可行的解决方案,但他们并没有满足我的要求。我不想在客户端浪​​费一个线程,我不想使用 svcutil.exe,我不想不接触服务器端让它保持同步。如果您没有注意到我的答案已链接到其他 3 个不同的 SO 问题。所以看起来我不是唯一一个认为我的答案还不错的人:) (2认同)

Jer*_*ert 5

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

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