Example #1
0
        /// <summary>
        /// Checks if received data is queued and optionally waits.
        /// </summary>
        /// <param name="bWait">
        /// A value of <c>true</c> makes this call blocking.
        /// </param>
        /// <param name="bSingle">
        /// A value of <c>true</c> causes the reader thread to stop
        /// after the next line received (single line mode).
        /// </param>
        /// <returns>
        /// - <c>true</c> if data is queued.
        /// </returns>
        /// <remarks>
        /// The underlying IMAP TCP/IP stream may have a timeout set, which can
        /// (when expired) cause this routine to return from blocking state.
        /// </remarks>
        protected bool ReaderPoll(bool bWait, bool bSingle)
        {
            if(stream == null) return false;        // called after close()

            // initialize the reader
            if(rdr_dlg == null)                     // see also ReaderStop()
            {   if(rdr_lines == null)               // only once
                    rdr_lines = new List<object>();
                rdr_dlg = new Reader(ReaderImpl);
                MonitorDebug("ReaderPoll: Initialise Reader");
                rdr_res = rdr_dlg.BeginInvoke(null, null);
            }

            // check background status - must lock!
            lock(rdr_lines)
            {   if(rdr_res.IsCompleted && stream != null)
                {   MonitorDebug("ReaderPoll: Continue Reader");
                    rdr_dlg.EndInvoke(rdr_res);     // would re-throw exception
                    rdr_res = rdr_dlg.BeginInvoke(null, null);
                }

                bool bok = rdr_lines.Count > 0;
                if(bSingle)                         // single line: request stop
                {   rdr_wait = true;
                    if(bok) return true;
                }
                else if(bok)                        // have data, don't stop
                {   rdr_wait = false;
                    return true;
                }
                else                                // for wait: request stop
                    rdr_wait = bWait;
            }

            // lock released - have no input
            if(!bWait)                              // no wait
                return false;

            // wait for the reader thread
            if(timeout == 0)
                rdr_res.AsyncWaitHandle.WaitOne();  // wait forever
            else
            {   if(!rdr_res.AsyncWaitHandle.WaitOne((int)timeout*1000, false))
                {   MonitorError("ReaderPoll: Timeout ");
                    haveTimeout = true;
                    return false;
                }
            }

            // restart reader
            if(ReaderPoll(false, bSingle)) return true;
            MonitorDebug("ReaderPoll: No Input after WaitOne");
            return ReaderPoll(true, bSingle);
        }