Не может иметь две операции в одном контракте с одинаковым именем (Async & Non)

Я получаю следующее исключение (не может иметь две операции в одном контракте с тем же именем, методы ExecuteAsync и Execute), когда активирована следующая служба.

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

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

Я думаю, это имеет смысл, если вы используете svcutil.exe для создания ссылки на службу, поскольку операции на основе задач создаются автоматически. Однако я не хочу добавлять ссылку на службу и вместо этого просто использую стандартный ChannelFactory для создания канала WCF. Есть ли другой способ, которым это возможно без переименования асинхронного метода в что-то другое? Или я должен обернуть метод синхронизации на клиенте в задаче.Бежать?

5 ответов


вышеизложенное недопустимо, потому что 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<byte[]> ExecuteAsync(MyRequest request);
    }
}

поскольку оба ServiceContracts имеют одинаковое имя, действие OperationContracts и ReplyAction одинаковы для методов async и sync. Теперь у клиента есть версия sync и async, а сервер остается неизмененным.


вы можете объявить либо, но не оба. WCF автоматически заставит любой метод работать в созданном прокси-сервере канала - вы можете подключить интерфейс, который использует асинхронный метод, к реализации, которая использует синхронизацию, и наоборот.

Если вы хотите поделиться определением интерфейса между кодом клиента и сервера (что не является необоснованным) и должны согласиться на один, ваш лучший выбор-асинхронный: предложение только синхронизации означает, что асинхронные клиенты должны тратить поток, предлагая только async означает, что вызывающие имеют выбор блокировать и тратить поток сами, если они должны. Поскольку вызов службы WCF включает ввод-вывод, вы определенно хотите предоставить клиенту возможность асинхронности, даже если сервер имеет реализацию синхронизации.


асинхронные методы-это конструкция .NET. Стандарт веб-служб не знает о них. вам не нужно ничего делать, чтобы позволить клиентам использовать асинхронные операции, потому что сервер и клиент независимы. выбрать синхронный или асинхронный отдельно для клиента и сервера.

поскольку этот факт часто приводит к недоверию, позвольте мне заявить следующее: Вы можете иметь сервер синхронизации с асинхронным клиентом и наоборот.


попробуйте добавить имя в OperationMethod, чтобы сделать его более простым.

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

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