• Avalanche.Core
Search Results for

    Show / Hide Table of Contents
    • Avalanche.Accessor
      • Introduction
      • IAccessor
        • IAccessor
        • IListAccessor
        • IMapAccessor
        • IRecordAccessor
        • IContentAccessor
        • IOneOfAccessor
        • IAnyAccessor
      • .Net
        • Introduction
        • IList<T>
        • IDictionary<K,V>
        • FieldInfo
        • OneOfAttribute
        • StructLayoutAttribute
        • Class
      • Protobuf
        • Introduction
      • Articles
        • Dependency Injection
        • AccessorMessages
    • Avalanche.Binding
      • Introduction
    • Avalanche.Core
      • License
    • Avalanche.DataType
      • Introduction
      • DataType
        • IDataType
        • IListType
        • IMapType
        • IRecordType
        • IFieldType
        • IOneOfType
        • IAnyType
        • IStringType
        • IValueType
        • IIntegerType
        • IEnumerationType
        • IRealType
      • .Net
        • Introduction
        • IList<T>
        • IDictionary<K,V>
        • FieldInfo
        • Enum
        • OneOfAttribute
        • StructLayoutAttribute
        • Class
      • Protobuf
        • Introduction
      • Articles
        • DataTypeRequest
        • PrintTree
        • DataTypeMessages
    • Avalanche.Emit
      • Introduction
      • TypeBuilder
      • ConstructorBuilder
      • MethodBuilder
      • PropertyBuilder
      • FieldBuilder
      • Emit
      • Utilities
    • Avalanche.FileSystem
      • Introduction
      • Abstractions
        • IFileSystem
          • IFileSystemBrowse
          • IFileSystemCreateDirectory
          • IFileSystemDelete
          • IFileSystemFileAttribute
          • IFileSystemMount
          • IFileSystemMove
          • IFileSystemObserve
          • IFileSystemOpen
        • IEvent
        • IEntry
        • IOption
        • IToken
      • FileSystem
      • VirtualFileSystem
      • MemoryFileSystem
      • EmbeddedFileSystem
      • HttpFileSystem
      • Decoration
      • IFileProvider
      • Events
      • Utilities
        • Dispose
        • File Scanner
        • Visit Tree
        • File Operation
    • Avalanche.Identity
      • Introduction
      • Identity
      • IdentityParts
      • IdentityInterner
      • IdentityComparer
      • Print Tree
      • IdentityAccessors
        • Introduction
        • TypeName
    • Avalanche.Localization
      • Introduction
      • Localization
      • LocalizationFile
      • LocalizationFiles
      • LocalizationFileSystem
      • LocalizationFileFormat
      • LocalizationLine
      • LocalizationLines
      • TemplateFormat
      • CultureProvider
      • FallbackCultureProvider
      • ResourceManager
      • LocalizationError
      • Microsoft.Extensions
        • Introduction
        • DependencyInjection
        • FileProvider
        • Logging
        • ITextLocalizer
        • IFileLocalizer
        • Localization
      • Asp.Net
        • Introduction
        • Supplying localization
        • Inject to pages
        • Culture Assigned
        • Minimalistic Api
        • Diagnostics
      • Pluralization
        • Introduction
        • Multiple plural parameters
        • Custom PluralRules
        • Invariant Culture
        • Unit Prefix
        • IPluralRule
        • IPluralNumber
        • IPluralRules
        • CLDRs
        • Unicode.CLDR40
        • Unicode.CLDR41
        • Unicode.CLDR42
      • Articles
        • Alphabet localization
        • Benchmarks
        • Caching
        • Class Library
        • Demo
        • Diagnostics
        • Embedded resources
        • Emplacement
        • File localization
        • Text localization
        • Printing templates
    • Avalanche.Message
      • Introduction
      • IMessage
      • IMessageProvider
      • IMessageDescription
      • IMessageDescriptions
      • MessageLevel
      • Message printing
      • Messages and Exceptions
      • Microsoft.Extensions
        • DependencyInjection
      • Articles
        • Aggregate Messages
        • Localization
        • Logging
        • Validation
    • Avalanche.Service
      • Introduction
      • Service
        • Introduction
        • IService
        • IServiceDisposable
        • IServiceDecoration
        • IServiceCast
        • IServiceObservable
        • IServiceContainer
        • Construction
        • Query
        • CancellationToken
        • CachePolicy
        • Scope
      • Handler
        • Introduction
        • IHandler
        • IHandlerCast
        • IHandlerDecoration
        • IHandlerWithOrder
        • CancellationToken
        • Cyclicity
        • Delegates
        • Invokable
        • ExportAttribute
        • OrderAttribute
        • PrintTree
        • Recursion
      • Query
        • Introduction
        • IQuery
        • IQueryCast
        • IQueryDecoration
      • Entry
        • Introduction
        • IEntry
        • IEntryCast
        • IEntryDecoration
        • IEntryObservable
        • IEntryVisitable
        • EntryState
      • Request
        • Introduction
        • IRequest
        • IRequestFor
        • IRequestToBeCached
        • IRequestToBeDisposed
        • RequestAttribute
        • ContextParameterAttribute
        • Print Tree
      • Dependency Injection
        • Introduction
        • Asp.Net
        • ServiceRequest<T>
        • Decorating a service
        • Handler
        • CachePolicy
        • CancellationToken
        • QueryLogger
      • Examples
        • NodeCount
        • Expression
        • Mapper
      • Articles
        • Benchmarks
        • Error Handling
        • ServiceMessages
    • Avalanche.StatusCode
      • Introduction
      • HResult
        • Introduction
        • HResult.Facilities
        • BasicMessages
        • RpcMessages
        • DispatchMessages
        • ItfMessages
        • Win32Messages
        • ClrMessages
      • System
        • Introduction
        • AccessControlMessages
        • AggregateMessages
        • AppDomainMessages
        • ArgumentMessages
        • ArgumentNullMessages
        • ArgumentOutOfRangeMessages
        • ArithmeticMessages
        • ArrayMessages
        • AssemblyMessages
        • BadImageFormatMessages
        • CodeContractMessages
        • CodePageMessages
        • CollectionsMessages
        • CompilerServiceMessages
        • CryptographyMessages
        • CultureMessages
        • DiagnosticsMessages
        • EventSourceMessages
        • ExecutionEngineMessages
        • FormatMessages
        • HostProtectionMessages
        • IOMessages
        • IndexOutOfRangeMessages
        • InteropServiceMessages
        • InvalidCastMessages
        • InvalidOperationMessages
        • IsolatedStorageMessages
        • LazyMessages
        • MarshalerMessages
        • MemoryMessages
        • MiscellaneousMessages
        • NotImplementedMessages
        • NotSupportedMessages
        • ObjectDisposedMessages
        • OperationCanceledMessages
        • OverflowMessages
        • PlatformMessages
        • PolicyMessages
        • PrincipalMessages
        • ProgramMessages
        • ReferenceMessages
        • ReflectionMessages
        • RegionMessages
        • RemotingMessages
        • ResourcesMessages
        • SecurityMessages
        • SerializationMessages
        • StackMessages
        • TaskMessages
        • TextMessages
        • ThreadingMessages
        • TimeZoneMessages
        • TypeMessages
        • XmlMessages
      • HttpStatusCode
      • OpcUaStatusCode
    • Avalanche.Template
      • Introduction
      • TemplateFormats
      • ITemplatePrintable
      • ITemplateFormatPrintable
      • ITemplateText
      • ITemplateBreakdown
      • ITemplateFormat
      • ITemplateFormats
      • Extract Arguments
      • Emplacement
    • Avalanche.Tokenizer
      • Introduction
      • IToken
      • ITokenizer
      • Tokenizers
    • Avalanche.Utilities
      • Introduction
      • Collections
        • Tuples
        • StructList
        • ArrayList
        • BijectionMap
        • LocakableDictionary
        • LockableList
        • MapList
        • Pipe
        • RingQueue
        • EnumerableExtensions
        • TupleUtilities
        • ArrayUtilities
      • Comparers
        • IGraphComparer
        • IGraphComparable
        • AlphaNumericComparer
        • EnumerableComparer
        • EnumerableGraphComparer
        • ReferenceComparer
        • KeyValuePairComparer
        • DefaultComparerProvider
        • RecordComparer
      • Cloners
        • ICloner
        • IGraphCloner
        • IGraphCloneable
        • ListCloner
        • DictionaryCloner
        • FieldCloner
        • PassthroughCloner
        • RecordCloner
        • ClonerProvider
      • Dispose
        • IDisposeAttachable
        • IDisposeBelatable
      • Provider
        • Introduction
        • ProviderBase
        • Delegate
        • Pipe
        • Cache
        • ResultCapture
        • AsReadOnly
        • AsService
        • IProviderEvent
      • Record
        • IRecordDescription
        • IFieldDescription
        • IConstructorDescription
        • IConstructionDescription
        • IParameterDescription
        • IRecordProviders
        • RecordDelegates
          • RecordCreate
          • RecordClone
          • RecordCopy
          • IRecordDelegates
        • FieldDelegates
          • FieldRead
          • FieldWrite
          • RecreateWith
          • IFieldDelegates
      • String
        • IEscaper
        • UnicodeString
      • Miscellaneous
        • IIdGenerator
        • Permutation
        • IReadOnly
        • IUserDataContainer
        • Void
    • Avalanche.Writer
      • Introduction
      • ConstantWriter
      • Context
      • ConvertWriter
      • DefaultConstructor
      • DelegateWriter
      • PassthroughWriter
      • Referer
      • TypeCast
      • Writer
      • WriterPipe
      • WriterMessages

    Service Cancellation

    Service lifetime token can be assigned with 'cancelToken:' parameter.

    // Create cancel signal source
    CancellationTokenSource serviceCancelSource = new CancellationTokenSource();
    // Get token
    CancellationToken serviceCancelToken = serviceCancelSource.Token;
    // Create service with cancel token
    IService service = Services.Create((ServiceHandlers.Instance, new DelayHandler()), cancelToken: serviceCancelToken);
    

    With ServiceBuilder the .AddCancellationToken(cancellationToken) method adds a token.

    // Create cancel signal source
    CancellationTokenSource serviceCancelSource = new CancellationTokenSource();
    // Get token
    CancellationToken serviceCancelToken = serviceCancelSource.Token;
    // Create service with cancel token
    IService service =
        new ServiceBuilder()
            .WithoutCache()
            .AddHandlers(ServiceHandlers.Instance)
            .AddHandler(new DelayHandler())
            .AddCancellationToken(serviceCancelToken)
            .Build();
    

    If this token is canceled, then all resolving stops and on-going queries throw OperationCanceledException.

    try
    {
        // Create request
        IRequestFor<Type> request = new TypeRequest("System.String");
        // Issue request to canceled service
        Task<Type?> task = service.GetAsync<IRequestFor<Type>, Type>(request);
        // Cancel service
        serviceCancelSource.Cancel();
        // Issue request to canceled service
        Type? type = await task;
    }
    catch (OperationCanceledException)
    {
        // Handle cancellation
        Console.WriteLine("Canceled");
    }
    

    Query Cancellation

    Query specific cancel token is added as 'cancelToken:' parameter.

    // Create cancel source
    CancellationTokenSource queryCancelSource = new CancellationTokenSource();
    // Get token
    CancellationToken queryCancelToken = queryCancelSource.Token;
    // Issue request
    Task<Type?> task = service.GetAsync<IRequestFor<Type>, Type>(request, cancelToken: queryCancelToken);
    

    The service resolver checks cancel token between handlers, if query is aborted, then OperationCanceledException is thrown.

    try
    {
        // Issue request
        Task<Type?> task = service.GetAsync<IRequestFor<Type>, Type>(request, cancelToken: queryCancelToken);
        // Cancel
        queryCancelSource.Cancel();
        // Wait
        Type? type = await task;
    }
    catch (OperationCanceledException)
    {
        // Handle cancellation
        Console.WriteLine("Canceled");
    }
    

    Query cancellation with cache

    If query is cached, then the query specific cancel token won't be applied.

    try
    {
        // Create service WITH cache
        IService service = Services.Create((ServiceHandlers.Instance, new DelayHandler()), CachePolicies.DefaultYes);
        // Create request
        IRequestFor<Type> request = new TypeRequest("System.String");
        // Create cancel source
        CancellationTokenSource queryCancelSource = new CancellationTokenSource();
        // Get token
        CancellationToken queryCancelToken = queryCancelSource.Token;
        // Issue request
        Task<Type?> task = service.GetAsync<IRequestFor<Type>, Type>(request, cancelToken: queryCancelToken);
        // Cancel (WON'T BE APPLIED due to caching)
        queryCancelSource.Cancel();
        // Wait
        Type? type = await task;
    }
    catch (OperationCanceledException)
    {
        // Handle cancellation
        Console.WriteLine("Canceled");
    }
    

    However if called with .GetAsyncQuickAbort() then execution returns to the caller on cancel signal, though the query will continue in the background and result will remain cached.

    try
    {
        // Create service WITH cache
        IService service = Services.Create((ServiceHandlers.Instance, new DelayHandler()), CachePolicies.DefaultYes);
        // Create request
        IRequestFor<Type> request = new TypeRequest("System.String");
        // Create cancel source
        CancellationTokenSource queryCancelSource = new CancellationTokenSource();
        // Get token
        CancellationToken queryCancelToken = queryCancelSource.Token;
        // Issue request
        Task<Type?> task = service.GetAsyncQuickAbort<IRequestFor<Type>, Type>(request, cancelToken: queryCancelToken);
        // Cancel 
        queryCancelSource.Cancel();
        // Wait (Aborts immediately, but resolve continues in the background and result is cached)
        Type? type = await task;
    }
    catch (OperationCanceledException)
    {
        // Handle cancellation
        Console.WriteLine("Canceled");
    }
    

    Cancellable query should be designed to implement IRequestNotToBeCached.

    public record MyQuery : IRequestNotToBeCached;
    

    Handler implementation

    Handler implementation gets access to cancel token from query.CancellationToken property. Typical implementation doesn't need to check for cancellation, but if implementation does blocking or makes API calls that may put thread into sleep, then it should check for cancel signal.

    If both service lifetime token and call tokens are used, then the query.CancellationToken represents the union of these the two.

    /// <summary>Example: Delays handling, but aborts on cancel token.</summary>
    public class DelayHandler : IHandlerAsync
    {
        [Order(-1000)]
        public async Task HandleAsync<Request, Response>(IQuery<Request, Response> query) where Request : notnull
        {
            // Got cancel token
            if (query.CancellationToken.CanBeCanceled)
            {
                await Task.Delay(100, query.CancellationToken);
            }
            // Did not get cancel token
            else
            {
                await Task.Delay(100);
            }
        }
    }
    

    Full Example

    Full example
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Avalanche.Service;
    
    public class service_cancel
    {
        public static async Task Run()
        {
            // Service cancellation
            {
                // <01>
                // Create cancel signal source
                CancellationTokenSource serviceCancelSource = new CancellationTokenSource();
                // Get token
                CancellationToken serviceCancelToken = serviceCancelSource.Token;
                // Create service with cancel token
                IService service = Services.Create((ServiceHandlers.Instance, new DelayHandler()), cancelToken: serviceCancelToken);
                // </01>
            }
            {
                // <02>
                // Create cancel signal source
                CancellationTokenSource serviceCancelSource = new CancellationTokenSource();
                // Get token
                CancellationToken serviceCancelToken = serviceCancelSource.Token;
                // Create service with cancel token
                IService service =
                    new ServiceBuilder()
                        .WithoutCache()
                        .AddHandlers(ServiceHandlers.Instance)
                        .AddHandler(new DelayHandler())
                        .AddCancellationToken(serviceCancelToken)
                        .Build();
                // </02>
    
                // <03>
                try
                {
                    // Create request
                    IRequestFor<Type> request = new TypeRequest("System.String");
                    // Issue request to canceled service
                    Task<Type?> task = service.GetAsync<IRequestFor<Type>, Type>(request);
                    // Cancel service
                    serviceCancelSource.Cancel();
                    // Issue request to canceled service
                    Type? type = await task;
                }
                catch (OperationCanceledException)
                {
                    // Handle cancellation
                    Console.WriteLine("Canceled");
                }
                // </03>
            }
    
    
            // Query cancellation
            {
                try
                {
                    // Create service
                    IService service = Services.Create((ServiceHandlers.Instance, new DelayHandler()));
                    // Create request
                    IRequestFor<Type> request = new TypeRequest("System.String");
                    // <11>
                    // Create cancel source
                    CancellationTokenSource queryCancelSource = new CancellationTokenSource();
                    // Get token
                    CancellationToken queryCancelToken = queryCancelSource.Token;
                    // Issue request
                    Task<Type?> task = service.GetAsync<IRequestFor<Type>, Type>(request, cancelToken: queryCancelToken);
                    // </11>
                    // Cancel
                    queryCancelSource.Cancel();
                    // Wait
                    Type? type = await task;
                }
                catch (OperationCanceledException)
                {
                    // Handle cancellation
                    Console.WriteLine("Canceled");
                }
            }
            {
                // Create service
                IService service = Services.Create((ServiceHandlers.Instance, new DelayHandler()));
                // Create request
                IRequestFor<Type> request = new TypeRequest("System.String");
                // Create cancel source
                CancellationTokenSource queryCancelSource = new CancellationTokenSource();
                // Get token
                CancellationToken queryCancelToken = queryCancelSource.Token;
                // <12>
                try
                {
                    // Issue request
                    Task<Type?> task = service.GetAsync<IRequestFor<Type>, Type>(request, cancelToken: queryCancelToken);
                    // Cancel
                    queryCancelSource.Cancel();
                    // Wait
                    Type? type = await task;
                }
                catch (OperationCanceledException)
                {
                    // Handle cancellation
                    Console.WriteLine("Canceled");
                }
                // </12>
            }
    
            // 
            {
                // <13>
                try
                {
                    // Create service WITH cache
                    IService service = Services.Create((ServiceHandlers.Instance, new DelayHandler()), CachePolicies.DefaultYes);
                    // Create request
                    IRequestFor<Type> request = new TypeRequest("System.String");
                    // Create cancel source
                    CancellationTokenSource queryCancelSource = new CancellationTokenSource();
                    // Get token
                    CancellationToken queryCancelToken = queryCancelSource.Token;
                    // Issue request
                    Task<Type?> task = service.GetAsync<IRequestFor<Type>, Type>(request, cancelToken: queryCancelToken);
                    // Cancel (WON'T BE APPLIED due to caching)
                    queryCancelSource.Cancel();
                    // Wait
                    Type? type = await task;
                }
                catch (OperationCanceledException)
                {
                    // Handle cancellation
                    Console.WriteLine("Canceled");
                }
                // </13>
            }
    
            {
                // <14>
                try
                {
                    // Create service WITH cache
                    IService service = Services.Create((ServiceHandlers.Instance, new DelayHandler()), CachePolicies.DefaultYes);
                    // Create request
                    IRequestFor<Type> request = new TypeRequest("System.String");
                    // Create cancel source
                    CancellationTokenSource queryCancelSource = new CancellationTokenSource();
                    // Get token
                    CancellationToken queryCancelToken = queryCancelSource.Token;
                    // Issue request
                    Task<Type?> task = service.GetAsyncQuickAbort<IRequestFor<Type>, Type>(request, cancelToken: queryCancelToken);
                    // Cancel 
                    queryCancelSource.Cancel();
                    // Wait (Aborts immediately, but resolve continues in the background and result is cached)
                    Type? type = await task;
                }
                catch (OperationCanceledException)
                {
                    // Handle cancellation
                    Console.WriteLine("Canceled");
                }
                // </14>
            }
        }
    }
    // <20>
    /// <summary>Example: Delays handling, but aborts on cancel token.</summary>
    public class DelayHandler : IHandlerAsync
    {
        [Order(-1000)]
        public async Task HandleAsync<Request, Response>(IQuery<Request, Response> query) where Request : notnull
        {
            // Got cancel token
            if (query.CancellationToken.CanBeCanceled)
            {
                await Task.Delay(100, query.CancellationToken);
            }
            // Did not get cancel token
            else
            {
                await Task.Delay(100);
            }
        }
    }
    // </20>
    
    // <15>
    public record MyQuery : IRequestNotToBeCached;
    // </15>
    
    In This Article
    Back to top Copyright © Toni Kalajainen