view Implab/AbstractTask.cs @ 232:133ba4444acc v2

Слияние
author cin
date Thu, 21 Sep 2017 01:14:27 +0300
parents dd4a3590f9c6
children
line wrap: on
line source

using System;
using System.Threading;

namespace Implab {
    /// <summary>
    /// Базовый класс для реализации задачь. Задача представляет собой некторое
    /// действие, которое можно иницировать и обработать результат его выполнения
    ///  в виде обещания, для этого оно реализует интерфейс <see cref="IPromise"/>.
    /// </summary>
    /// <remarks>
    /// Данный класс определяет стандартное поведение при обработки результатов, в частности
    /// обработку <see cref="System.OperationCanceledException"/> и <see cref="PromiseTransientException"/>
    /// </remarks>
    public abstract class AbstractTask : AbstractPromise {
        int m_cancelationLock;

        /// <summary>
        /// Получает эксклюзивное право отмены задания, используется для отмены задания до начала его выполнения.
        /// </summary>
        /// <returns><c>true</c>, if cancelation was locked, <c>false</c> otherwise.</returns>
        protected bool LockCancelation() {
            return 0 == Interlocked.CompareExchange(ref m_cancelationLock, 1, 0);
        }



        protected void SetErrorInternal(Exception error) {
            // unwrap 
            while (error is PromiseTransientException && error.InnerException != null)
                error = error.InnerException;
            
            if (error is OperationCanceledException)
                SetCancelled(error);
            else
                SetError(error);
        }

        protected void SetCancelledInternal(Exception reason) {
            SetCancelled(
                reason == null ? new OperationCanceledException() : reason is OperationCanceledException ? reason : new OperationCanceledException(null, reason)
            );
        }
    }
}