Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

Вот что я сделал. У меня есть два отдельных контракта. Один для клиента и один для сервера:

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 имеют одно и то же имя, ActionContracts Action и ReplyAction одинаковы для методов async и sync. Теперь клиент имеет как синхронизацию, так и асинхронную версию, и сервер остается неизменным.

Ответ 2

Вышеприведенное недействительно, поскольку сам WCF делает два метода для каждого OperationContract в вашем случае Execute() один синхронный и второй асинхронный, который можно вызывать на стороне клиента, написав ServiceClientObj.ExexuteAsync(request), поэтому вам не нужно добавлять асинхронный метод явно в IMyService. Сама основа отвечает за генерацию метода async для каждой операции

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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

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

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