1a48aae2创建于 2019年4月18日历史提交
/*----------------------------------------------------------------------------------

// Copyright 2019 Huawei Technologies Co.,Ltd.

// Licensed under the Apache License, Version 2.0 (the "License"); you may not use

// this file except in compliance with the License.  You may obtain a copy of the

// License at

//

// http://www.apache.org/licenses/LICENSE-2.0

//

// Unless required by applicable law or agreed to in writing, software distributed

// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR

// CONDITIONS OF ANY KIND, either express or implied.  See the License for the

// specific language governing permissions and limitations under the License.

//----------------------------------------------------------------------------------*/

using System;

using System.Threading;



namespace OBS.Internal

{

    internal class ObsAsyncResult<V> : IAsyncResult, IDisposable

    {

        protected readonly object _state;



        protected readonly ManualResetEvent _event;



        protected AsyncCallback _callback;



        protected Exception _exception;



        protected bool _isCompleted = false;



        protected bool _disposed = false;



        protected V _result;



        public ObsAsyncResult(AsyncCallback callback, object state)

        {

            this._callback = callback;

            this._state = state;

            this._event = new ManualResetEvent(false);

        }



        public bool IsCompleted

        {

            get { return this._isCompleted; }

        }



        public WaitHandle AsyncWaitHandle

        {

            get

            {

                if (this._isCompleted)

                {

                    this._event.Set();

                }

                return this._event;

            }

        }



        public AsyncCallback AsyncCallback

        {

            get { return this._callback; }

        }



        public object AsyncState

        {

            get { return this._state; }

        }



        public bool CompletedSynchronously

        {

            get;

            set;

        }



        public V Get()

        {

            if (!this._isCompleted)

            {

                this._event.WaitOne();

            }



            if (this._exception != null)

            {

                throw this._exception;

            }

            return this._result;

        }



        public virtual V Get(int millisecondsTimeout)

        {

            if (!this._isCompleted)

            {

                if (!this._event.WaitOne(millisecondsTimeout))

                {

                    throw new TimeoutException();

                }

            }



            if (this._exception != null)

            {

                throw this._exception;

            }

            return this._result;

        }



        public virtual void Reset(AsyncCallback callback)

        {

            if (this._disposed)

            {

                throw new ObjectDisposedException("IAsyncResult is disposed");

            }

            this._isCompleted = false;

            this._event.Reset();

            this._result = default(V);

            this._exception = null;

            if(callback != null)

            {

                this._callback = callback;

            }

        }



        private void Notify()

        {

            this._isCompleted = true;

            if (!_disposed)

            {

                this._event.Set();

            }

            this._callback?.Invoke(this);

        }



        public void Set(V result)

        {

            this._result = result;

            this.Notify();

        }



        public void Set(Exception ex)

        {

            this._exception = ex;

            this.Notify();

        }



        protected virtual void Dispose(bool disposing)

        {

            if (!_disposed)

            {

                _disposed = true;

                if (disposing && this._event != null)

                {

                    this._event.Close();

                }

            }

        }



        public void Dispose()

        {

            Dispose(true);

            GC.SuppressFinalize(this);

        }



    }

}