Cannot have two operations in the same contract wi

2019-02-08 05:37发布

问题:

I get the following exception (Cannot have two operations in the same contract with the same name, methods ExecuteAsync and Execute) when the following service is activated.

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

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

I guess this makes sense if you are using the svcutil.exe to create your service reference, because the task-based operations are created automatically for you. However, I don't want to add a service reference and instead just use the standard ChannelFactory to create the WCF Channel. Is there any other way this is possible without renaming the async method to something else? Or must I wrap the sync method on the client in a Task.Run?

回答1:

The above is not valid because WCF itself makes two methods for each OperationContract in your case Execute() one synchronous and second asynchronous, which can be called on client side by writing ServiceClientObj.ExexuteAsync(request), so you don't need to add async method explicitly in the IMyService.The Framework is itself responsible for generating async method of each Operation



回答2:

Here's what I did. I have two separate contracts. One for the client and one for the server:

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

Because both ServiceContracts share the same name, the OperationContracts' Action and ReplyAction are the same for the async and sync methods. The client now has both the sync and async version and the server stays unmodified.



回答3:

You can declare either, but not both. WCF will automatically make either method work in the generated channel proxy -- you can connect an interface that uses an async method to an implementation that uses a sync one, and vice versa.

If you want to share the interface definition across client and server code (which is not unreasonable) and have to settle for one, your best bet is the async one: offering only sync means async clients must waste a thread, while offering only async means callers have the choice to block and waste the thread themselves if they have to. As calling a WCF service involves I/O, you definitely want to give the client the option for async, even if the server has a sync implementation.



回答4:

Async methods are a .NET construct. The Web Services standard does not know about them. You do not need to do anything to enable clients to use async operations because server and client are independent. Pick sync or async independently for client and server.

Since this fact often results in disbelief let me state the following: You can have a sync server with an async client and the other way around.



回答5:

Try adding the name in OperationMethod to make it more simpler.

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

    [OperationContract(Name = "Service2")]
    Task<byte[]> ExecuteAsync(MyRequest request);
}


标签: c# wcf .net-4.5