/// <summary>
        /// Watches this instance.
        /// </summary>
        protected virtual void Watch()
        {
            var idleIntervalInMillisecond = Options.IdleInterval * 1000;

            if (idleIntervalInMillisecond < 1000)
            {
                idleIntervalInMillisecond = 5000;
            }
            var  batchSize = (!Options.BatchSize.HasValue || Options.BatchSize.Value < 1 || Options.BatchSize.Value > 20) ? 1 : Options.BatchSize.Value;
            bool needIdle  = false;

            while (true)
            {
                try
                {
                    var items = QueueMessageOperator.GetMessages(batchSize, Options.InvisibilityTimeout);

                    if (items.HasItem())
                    {
                        needIdle = false;

                        if (items.Count == 1)
                        {
                            Task.WaitAll(Task.Factory.StartNew(Dispatch, items.FirstOrDefault()));
                        }
                        else
                        {
                            Task.WaitAll(items.Select(x => Task.Factory.StartNew(Dispatch, x)).ToArray());
                        }
                    }
                    else
                    {
                        needIdle = true;
                    }

                    needIdle = !items.HasItem();
                }
                catch (Exception ex)
                {
                    needIdle = true;
                    WriteException(ex.Handle());
                }

                if (needIdle)
                {
                    Thread.Sleep(idleIntervalInMillisecond);
                }
            }
        }
        /// <summary>
        /// Dispatches the specified object.
        /// </summary>
        /// <param name="obj">The object.</param>
        /// <returns></returns>
        protected void Dispatch(object obj)
        {
            QueueMessageItem <T> message = obj as QueueMessageItem <T>;

            try
            {
                message.CheckNullObject(nameof(message));
                var result = Process(message);
                result.CheckNullObject(nameof(result));

                if (result.IsSucceed)
                {
                    QueueMessageOperator.DeleteMessage(message.Id, result.Receipt);
                }
                else if (result.Exception != null)
                {
                    throw result.Exception;
                }
            }
            catch (Exception ex)
            {
                WriteException(ex.Handle(new { message }));
            }
        }