/// <summary> /// Sends an email. /// </summary> /// <param name="to">Email addresses, comma or semicolon separated, to send to (using the "Bcc" field). Validation errors are silently ignored and may result in no email being sent.</param> /// <param name="subject">Subject line</param> /// <param name="body">Body</param> /// <param name="bodyHtml">If true, the body is an HTML body.</param> public static void SendEmail(string to, string subject, string body, bool bodyHtml) { if (!Enabled) { return; } MailMessage message = new MailMessage(); message.From = new MailAddress(Settings.data.smtpSendFrom); string[] allToAddresses = to.Split(";,".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); foreach (string toAddress in allToAddresses) { try { message.Bcc.Add(toAddress.Trim()); } catch (FormatException) { } } if (message.Bcc.Count == 0) { return; } message.Subject = subject; message.Body = body; message.IsBodyHtml = bodyHtml; pool.Enqueue(() => { using (SmtpClient client = new SmtpClient()) { client.Host = Settings.data.smtpHost; client.Port = Settings.data.smtpPort; client.EnableSsl = Settings.data.smtpSsl; if (!string.IsNullOrEmpty(Settings.data.smtpUser) && !string.IsNullOrEmpty(Settings.data.smtpPass)) { client.Credentials = new NetworkCredential(Settings.data.smtpUser, Settings.data.smtpPass); } try { client.Send(message); } catch (Exception ex1) { Logger.Debug(ex1, "Failed to send email (attempt 1/2)"); Thread.Sleep(1000); try { client.Send(message); } catch (Exception ex2) { Logger.Debug(ex2, "Failed to send email (attempt 2/2)"); } } } }); }
/// <summary> /// Performs an asynchronous, multi-threaded traceroute operation. /// </summary> /// <param name="threadPool">A thread pool upon which to execute the pings. It should contain as many threads as the <see cref="MaxHops"/> value.</param> /// <param name="token">An object which should be passed through to the OnHostResult method.</param> /// <param name="Target">The target host to ping.</param> /// <param name="MaxHops">The maximum number of hops to try.</param> /// <param name="OnHostResult">Callback method which will be called with the result of each individual ping.</param> /// <param name="PingTimeoutMs">Timeout in milliseconds after which the ping should be considered unsuccessful.</param> public static void TraceRoute(SimpleThreadPool threadPool, object token, IPAddress Target, byte MaxHops, Action <TraceRouteHostResult> OnHostResult, int PingTimeoutMs = 5000) { byte[] buffer = new byte[0]; for (byte ttl = 1; ttl <= MaxHops; ttl++) { object state = new { token, ttl, Target, MaxHops, OnHostResult, PingTimeoutMs, buffer }; threadPool.Enqueue(() => { PingSync(state); }); } }
public void TestThreadPoolStopping() { SimpleThreadPool p = new SimpleThreadPool("Test Pool", 2, 6, 60000, true, (e, s) => Assert.Fail(e?.ToString() + " " + s)); Thread.Sleep(250); Assert.AreEqual(2, p.MinThreads); Assert.AreEqual(6, p.MaxThreads); Assert.AreEqual(0, p.CurrentBusyThreads); Assert.AreEqual(2, p.CurrentIdleThreads); Assert.AreEqual(2, p.CurrentLiveThreads); p.Enqueue(() => { Thread.Sleep(1000); }); Thread.Sleep(250); Assert.AreEqual(2, p.MinThreads); Assert.AreEqual(6, p.MaxThreads); Assert.AreEqual(1, p.CurrentBusyThreads); Assert.AreEqual(1, p.CurrentIdleThreads); Assert.AreEqual(2, p.CurrentLiveThreads); p.Stop(); Thread.Sleep(250); Assert.AreEqual(2, p.MinThreads); Assert.AreEqual(6, p.MaxThreads); Assert.AreEqual(1, p.CurrentBusyThreads); Assert.AreEqual(0, p.CurrentIdleThreads); Assert.AreEqual(1, p.CurrentLiveThreads); Thread.Sleep(750); Assert.AreEqual(2, p.MinThreads); Assert.AreEqual(6, p.MaxThreads); Assert.AreEqual(0, p.CurrentBusyThreads); Assert.AreEqual(0, p.CurrentIdleThreads); Assert.AreEqual(0, p.CurrentLiveThreads); }
public void TestThreadExpiration() { SimpleThreadPool p = new SimpleThreadPool("Test Pool", 0, 2, 200, true, (e, s) => Assert.Fail(e?.ToString() + " " + s)); Thread.Sleep(250); Assert.AreEqual(0, p.MinThreads); Assert.AreEqual(2, p.MaxThreads); Assert.AreEqual(0, p.CurrentBusyThreads); Assert.AreEqual(0, p.CurrentIdleThreads); Assert.AreEqual(0, p.CurrentLiveThreads); p.Enqueue(() => { Thread.Sleep(200); }); Assert.AreEqual(0, p.MinThreads); Assert.AreEqual(2, p.MaxThreads); Assert.AreEqual(1, p.CurrentBusyThreads); Assert.AreEqual(0, p.CurrentIdleThreads); Assert.AreEqual(1, p.CurrentLiveThreads); Thread.Sleep(250); Assert.AreEqual(0, p.MinThreads); Assert.AreEqual(2, p.MaxThreads); Assert.AreEqual(0, p.CurrentBusyThreads); Assert.AreEqual(1, p.CurrentIdleThreads); Assert.AreEqual(1, p.CurrentLiveThreads); Thread.Sleep(250); Assert.AreEqual(0, p.MinThreads); Assert.AreEqual(2, p.MaxThreads); Assert.AreEqual(0, p.CurrentBusyThreads); Assert.AreEqual(0, p.CurrentIdleThreads); Assert.AreEqual(0, p.CurrentLiveThreads); }