Как позвонить прокси-серверу службы удаленного взаимодействия Azure с CancellationToken?

На основе примера документации, прокси создается следующим образом:

IMyService helloWorldClient = ServiceProxy.Create<IMyService>(new 
Uri("fabric:/MyApplication/MyHelloWorldService"));

string message = await helloWorldClient.HelloWorldAsync();

Но при условии, что мне нужно ограничить максимальное время ответа, я обычно создаю CancellationToken и передаю его вызову. Есть ли способ, как передать токен прокси, чтобы он отменял ожидание результата от удаленного сервиса?

3 ответа

Вы можете сделать это в стеке V2, я не пробовал стек V1, но он также может работать там. Добавьте параметр типа CancellationToken в сигнатуру метода:

void HelloWorldAsync(CancellationToken cancellationToken);

этот токен будет затем передан методу ServicePartitionClient.InvokeWithRetryAsync через прокси.

Сгенерированный метод прокси будет выглядеть следующим образом:

Task<string> IMyService.HelloWorldAsync(CancellationToken cancellationToken)
{
    IServiceRemotingRequestMessageBody serviceRemotingRequestMessageBody = base.CreateRequestMessageBodyV2("MyNamespace.IMyService", "HelloWorldAsync", 1);
    Task<IServiceRemotingResponseMessageBody> task = base.InvokeAsyncV2(
    1, -1, "HelloWorldAsync", serviceRemotingRequestMessageBody,
    cancellationToken);
    return base.ContinueWithResultV2<ServiceInfoResponse>(task);
}

Без параметра CancellationToken прокси-метод выглядит так:

Task<string> IMyService.HelloWorldAsync()
{
    IServiceRemotingRequestMessageBody serviceRemotingRequestMessageBody = base.CreateRequestMessageBodyV2("MyNamespace.IMyService", "HelloWorldAsync", 1);
    Task<IServiceRemotingResponseMessageBody> task = base.InvokeAsyncV2(
    1, -1, "HelloWorldAsync", serviceRemotingRequestMessageBody,
    CancellationToken.None);
    return base.ContinueWithResultV2<ServiceInfoResponse>(task);
}

Если вы хотите проверить сгенерированную сборку прокси, используйте следующий атрибут в сборке EntryPoint или сборке, для которой определен интерфейс службы:

[assembly: CodeBuilder(EnableDebugging = true)]

Кому все еще интересно правильно делать то, что просит эта ветка, может ли ссылка ниже быть ответом?

https://blogs.msdn.microsoft.com/azureservicefabric/2016/02/23/service-fabric-sdk-v1-5-175-and-the-adoption-of-virtual-machine-scale-sets/

Содержание:

CancellationToken поддержка для IService/IActor

Методы Reliable Service и Reliable Actor теперь поддерживают токен отмены, который можно удалить с помощью ActorProxy и ServiceProxy, что позволяет реализовать совместное аннулирование. Клиенты, которые хотят отменить долгосрочную службу или метод субъекта, могут сигнализировать токен отмены, и это намерение отмены будет распространено на метод субъекта / службы. Затем этот метод может определить, когда остановить выполнение, посмотрев на состояние его аргумента токена отмены.

Например, контракт актера, который может иметь долгосрочный метод, может быть смоделирован, как показано ниже:

    public interface IPrimeNumberActorInterface : IActor
    {

        Task<ulong> FindNextPrimeNumberAsync
            (ulong previous, CancellationToken cancellationToken);

    }

Код клиента, который желает отменить выполнение метода, может сообщить о своем намерении, отменив токен отмены.

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

Чтобы выполнить то, что вы хотите, отмените операцию через определенное время, вы должны настроить FabricTransportRemotingListenerSettings и установить для OperationTimeout желаемое время ожидания. По умолчанию это 5 минут.

Вы также можете сделать этот параметр через TransportSettings в сервисе settings.xml.

Следующая ссылка покажет оба примера того, как установить конфигурации FabricTransportRemotingListenerSettings или TransportSettings. https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-secure-communication

Документация не отображается, но параметр, который вы должны установить: OperationTimeout

То же самое можно сделать для актеров, смотрите здесь, обратите внимание, что для актеров некоторые настройки отличаются.

Другие вопросы по тегам