/// <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); }