コード例 #1
0
        public E Take(int timeout)
        {
            lock (_monitor) {
                if (_sendRequestQueue.Count != 0)
                {
                    SendRequest <E> sendRequest = _sendRequestQueue.First.Value;
                    _sendRequestQueue.RemoveFirst();
                    if (sendRequest.IsBlocking)
                    {
                        sendRequest.Done = true;
                        Monitor.Pulse(_monitor);
                    }

                    return(sendRequest.Message);
                }

                Request <E> request = new Request <E>();
                _requestQueue.AddLast(request);

                TimeoutHolder timeoutHolder = new TimeoutHolder(timeout);
                do
                {
                    try {
                        if (timeoutHolder.Value <= 0L)
                        {
                            _requestQueue.Remove(request);
                            return(default);
コード例 #2
0
        public bool Transfer(E message, int timeout)
        {
            lock (_monitor) {
                if (_requestQueue.Count != 0)
                {
                    Request <E> request = _requestQueue.First.Value;
                    _requestQueue.RemoveFirst();
                    request.Message = message;
                    request.Done    = true;
                    Monitor.Pulse(_monitor);
                }
                else
                {
                    SendRequest <E> request = new SendRequest <E>(message, BLOCKING);
                    _sendRequestQueue.AddLast(request);
                    TimeoutHolder timeoutHolder = new TimeoutHolder(timeout);
                    do
                    {
                        try {
                            if (timeoutHolder.Value <= 0L)
                            {
                                _sendRequestQueue.Remove(request);
                                return(false);
                            }

                            Monitor.Wait(_monitor, timeout);
                        }
                        catch (ThreadInterruptedException ie) {
                            if (request.Done)
                            {
                                Thread.CurrentThread.Interrupt();
                                break;
                                //will return true after the interruption, because the operation succeeded
                            }

                            _sendRequestQueue.Remove(request);
                            throw ie;
                        }
                    } while (_requestQueue.Count == 0);
                }

                return(true);
            }
        }