private void SendCompleted(object sender, AsyncCompletedEventArgs e) { SmtpWorkerAsyncResult completedAsyncResult = (SmtpWorkerAsyncResult)e.UserState; if (e.Error != null) { Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "SendCompleted Exception: {0}", e.Error)); } completedAsyncResult.Complete(e.Error, false); completedAsyncResult.Dispose(); // Use the completed thread to check for any new messages in queue var smtpClient = (SmtpClient)sender; ProcessQueue(smtpClient); }
private void ProcessQueue(SmtpClient clientToUse) { SmtpWorkerAsyncResult asyncResultToProcess = null; lock (queueLock) { // lock keeps queue count and active client count in sync if (messageQueue.Count > 0) { asyncResultToProcess = messageQueue.Dequeue(); Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:mm':'ss.ffffff}: ProcessQueue, active count = {1}, queue length = {2}", DateTimeOffset.Now, activeSmtpClients.Count, messageQueue.Count)); } else { // Nothing to process; shut down the SmtpClient activeSmtpClients.Remove(clientToUse); } }; if (asyncResultToProcess != null) { Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:mm':'ss.ffffff}: Before SendAsync, active count = {1}, queue length = {2}", DateTimeOffset.Now, activeSmtpClients.Count, messageQueue.Count)); Exception exception = null; try { clientToUse.SendAsync(asyncResultToProcess.Message, asyncResultToProcess); } catch (Exception ex) { exception = ex; Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "SendAsync Exception: {0}", exception)); } Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:mm':'ss.ffffff}: After SendAsync, active count = {1}, queue length = {2}", DateTimeOffset.Now, activeSmtpClients.Count, messageQueue.Count)); if (exception != null) { asyncResultToProcess.Complete(exception, true); } } else { TryDisposeSmtpClient(clientToUse); } }
private void ThreadStart() { Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:mm':'ss.ffffff}: ThreadStart, pool count = {1}, queue length = {2}", DateTimeOffset.Now, pool.smtpWorkerPool.Count, pool.messageQueue.Count)); SmtpClient smtpClient = null; try { smtpClient = new SmtpClient(); Stopwatch idleTimeout = new Stopwatch(); bool running = true; while (running) { SmtpWorkerAsyncResult asyncResultToProcess = null; lock (pool.queueLock) { // lock keeps queue count and active client count in sync if (pool.messageQueue.Count > 0) { asyncResultToProcess = pool.messageQueue.Dequeue(); } else { if (idleTimeout.IsRunning && idleTimeout.ElapsedMilliseconds > idleTimeoutMilliseconds) { pool.smtpWorkerPool.Remove(this); running = false; } } } if (asyncResultToProcess != null) { if (idleTimeout.IsRunning) { isIdle = false; idleTimeout.Reset(); } var message = asyncResultToProcess.Message; Exception exception = null; try { Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:mm':'ss.ffffff}: Before Send, pool count = {1}, queue length = {2}", DateTimeOffset.Now, pool.smtpWorkerPool.Count, pool.messageQueue.Count)); smtpClient.Send(message); Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:mm':'ss.ffffff}: After Send, pool count = {1}, queue length = {2}", DateTimeOffset.Now, pool.smtpWorkerPool.Count, pool.messageQueue.Count)); } catch (Exception ex) { exception = ex; Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Error sending: {0}", exception)); } asyncResultToProcess.Complete(exception, false); } else { if (!idleTimeout.IsRunning) { isIdle = true; idleTimeout.Start(); } } Thread.Sleep(0); } } catch (Exception ex) { Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:mm':'ss.ffffff}: Exception: {1}", DateTimeOffset.Now, ex)); } finally { if (smtpClient != null) { TryDisposeSmtpClient(smtpClient); } } Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:mm':'ss.ffffff}: ThreadEnding, pool count = {1}, queue length = {2}", DateTimeOffset.Now, pool.smtpWorkerPool.Count, pool.messageQueue.Count)); }