Search The ForumSearch   RegisterRegister  LoginLogin

MailBee.NET SMTP

 AfterLogic Forum : MailBee.NET SMTP
Subject Topic: Sending multiple emails via threads Post ReplyPost New Topic
Author
Message << Prev Topic | Next Topic >>
Neil_Knight
Newbie
Newbie


Joined: 06 December 2011
Location: United Kingdom
Online Status: Offline
Posts: 30
Posted: 20 January 2012 at 4:47am | IP Logged Quote Neil_Knight

I am creating an application that is sending multiple emails via threads. I'm using the SMTP class in order to create my emails and send. When I run the application with 1 thread, the system works fine. If I increase the number of threads, then I get input in the log files from other threads, even though they aren't logging to that file. This is breaking the whole system. Any idea as to why a thread is interrupting another thread? Is the SMTP class thread-safe?
Back to Top View Neil_Knight's Profile Search for other posts by Neil_Knight
 
Igor
AfterLogic Support
AfterLogic Support


Joined: 24 June 2008
Location: United States
Online Status: Offline
Posts: 6104
Posted: 20 January 2012 at 5:13am | IP Logged Quote Igor

Is my understanding correct that you are using single SMTP object instance for all the threads? If yes, they will all use a single log file, and you'll need to make sure SyncRoot property is set correctly. It is still possible to have different log file for different thread, the example is available here. Alternately, you can simply use separate SMTP object instance per thread, that should not affect overall performance.

--
Regards,
Igor, AfterLogic Support
Back to Top View Igor's Profile Search for other posts by Igor
 
Neil_Knight
Newbie
Newbie


Joined: 06 December 2011
Location: United Kingdom
Online Status: Offline
Posts: 30
Posted: 20 January 2012 at 5:40am | IP Logged Quote Neil_Knight

Hi Igor,
I am using seperate Threads in order to instantiate an SMTP object and then connect, configure and send the email.
Back to Top View Neil_Knight's Profile Search for other posts by Neil_Knight
 
Neil_Knight
Newbie
Newbie


Joined: 06 December 2011
Location: United Kingdom
Online Status: Offline
Posts: 30
Posted: 20 January 2012 at 6:30am | IP Logged Quote Neil_Knight

Here is an example from the log file:

[14:19:28.68] [INFO] Socket connected to IP address 68.232.135.98 on port 25.
[14:19:30.16] [INFO] Connected to mail service at host "mx1.dhl.iphmx.com" on port 25 and ready.
[14:19:30.16] [INFO] Will send Hello command (HELO or EHLO).
[14:19:30.31] [INFO] SMTP Hello completed.
[14:19:30.43] [INFO] Will send mail message to SMTP server "mx1.dhl.iphmx.com".
[14:19:30.45] [INFO] Will submit sender and recipients.
[14:19:30.93] [INFO] Sender and recipients accepted by SMTP server. Will send message data now.
[14:19:32.15] [INFO] Message successfully submitted to SMTP server.
[14:19:32.62] [INFO] Will disconnect from host "mx1.dhl.iphmx.com".
[14:19:32.62] [INFO] Disconnected from host "mx1.dhl.iphmx.com".
[14:19:37.88] [INFO] Will send Hello command (HELO or EHLO).

The last line shouldn't be there.
Back to Top View Neil_Knight's Profile Search for other posts by Neil_Knight
 
Alex
AfterLogic Support
AfterLogic Support
Avatar

Joined: 19 November 2003
Online Status: Offline
Posts: 2206
Posted: 21 January 2012 at 12:23am | IP Logged Quote Alex

To confirm, you're saying that you have multiple instances of Smtp class, each instance running in its own thread, and has its own log file path assigned. Somehow, the log data for Smtp instance #1 appear in the log file for Smtp instance #2.

If you set LogFormatOptions.AddContextInfo flag in Logger.Format property, what do you get?

Regards,
Alex
Back to Top View Alex's Profile Search for other posts by Alex
 
Neil_Knight
Newbie
Newbie


Joined: 06 December 2011
Location: United Kingdom
Online Status: Offline
Posts: 30
Posted: 21 January 2012 at 1:13am | IP Logged Quote Neil_Knight

Hi,
I think it might be easier to let you know what I'm trying to do and then you can (kindly) offer the best way of using your component?

I have lots of email addresses in a database, randomly ordered. I select 10 records where they have the same email domain. I then create a new thread and connect to the domain, configure the email with the recipients information and then send it and repeat until I've got no records left. All output goes to a GUID named log file making it unique to the instance of the Smtp object.

This process works when 1 thread is running. When I have multiple threads, it's as if the process messes up some what. It's like it doesn't follow the same pattern that is working for 1 thread.

I'd like to know how I can capture any error that is thrown when the Smtp object is connected and sending/receiving data. Is there an Event Handler that I can hook into? Currently I'm using the MailBee....Exception, but that doesn't seem to work all of the time. If there is an Event Handler for any SMTP error codes, that would make my application logic a lot cleaner too :o)

Thanks
Back to Top View Neil_Knight's Profile Search for other posts by Neil_Knight
 
Alex
AfterLogic Support
AfterLogic Support
Avatar

Joined: 19 November 2003
Online Status: Offline
Posts: 2206
Posted: 21 January 2012 at 2:10am | IP Logged Quote Alex

Quote:
I then create a new thread and connect to the domain

You're NOT using SMTP relay server, correct? Why so, is it for a purpose? Also, when you mention "connect to the domain", do you mean "connect to MX of that domain"? And what if the domain has multiple MXes, some of them are dead?

Quote:
I'd like to know how I can capture any error that is thrown when the Smtp object is connected and sending/receiving data

Smtp class has a number of events including Smtp.ErrorOccurred, Smtp.MessageSent and Smtp.MessageNotSent. They, in turn, have a number of properties like the description of the error, the list of accepted or failed recipients, etc.

Smtp.MessageNotSent event makes sense only when you send multiple messages with a single command (like Smtp.SendJobs). Failure to send a single email (Smtp.Send) throws an exception rather than firing an event.

ErrorOccurred event fires whenever any problem occurred, even if this problem was not critical (warning). You can find more detailed explanations in the docs.

Regards,
Alex
Back to Top View Alex's Profile Search for other posts by Alex
 
Alex
AfterLogic Support
AfterLogic Support
Avatar

Joined: 19 November 2003
Online Status: Offline
Posts: 2206
Posted: 21 January 2012 at 2:16am | IP Logged Quote Alex

BTW, error codes and error messages are there too. ErrorOccurred event provides the exception which originated it, through Reason property. And it, like any other MailBeeException, has ErrorCode property which contains that code.

Note that the exception in ErrorOccurred event is just an object, it's not necessarily thrown to the application. Only if IsFinalError is true, MailBee throws the same exception to the application once ErrorOccurred event handler completes.

Regards,
Alex
Back to Top View Alex's Profile Search for other posts by Alex
 
Neil_Knight
Newbie
Newbie


Joined: 06 December 2011
Location: United Kingdom
Online Status: Offline
Posts: 30
Posted: 21 January 2012 at 10:55am | IP Logged Quote Neil_Knight

Hi Alex,
I select the records from the database and then create a new thread to talk the the MX server of say Hotmail.com. I am not using a Relay server as I need to do some additional data tracking with regards to the SMTP chat between our servers and the email MX servers.

If I am looping through a data set, and I've configured the ErrorOccurred event, will this break out of the loop? Or does that depend on how I configure a try/catch block around the loop?

If an error does occur, does the code carry on from where it left off?
Back to Top View Neil_Knight's Profile Search for other posts by Neil_Knight
 
Neil_Knight
Newbie
Newbie


Joined: 06 December 2011
Location: United Kingdom
Online Status: Offline
Posts: 30
Posted: 21 January 2012 at 10:57am | IP Logged Quote Neil_Knight

I guess that I can use the ErrorOccurred event in order to reduce some of my code from trying to catch individual exceptions after reading your post. Can I cast the object in the ErrorOccurred event to an Smtp type in order to retrieve more details from the Smtp object? I know that I'll have ErrorCodes and Reason in the EventArgs object.
Back to Top View Neil_Knight's Profile Search for other posts by Neil_Knight
 
Alex
AfterLogic Support
AfterLogic Support
Avatar

Joined: 19 November 2003
Online Status: Offline
Posts: 2206
Posted: 21 January 2012 at 12:46pm | IP Logged Quote Alex

ErrorOccurred event does not control whether to continue execution or not. It depends on your try/catch block. When an exception occurs (I'm talking about "real" exceptions which are propagated to your application, i.e. those which have IsFinalError=true in ErrorOccurred parameters), your application should catch it, analyze it and decide what to do next. MailBee provides very extensive set of exceptions so you can do different things for different exceptions. Also, the state of Smtp object after exception varies upon exception type.

For instance, if the exception implements IMailBeeSocketMustCloseException interface, this means MailBee had to close the connection as this exception is not recoverable. Some exceptions like those which implement IMailBeeNegativeSmtpResponseException interface do not close the connection and you can proceed (for instance, provide other login credentials if the previous attempt failed).

And yes, you can query Smtp object properties and status methods (like GetMaxMessageSize) in ErrorOccurred event. However, it's only allowed if the Smtp instance has only 1 thread. But because you have only 1 thread per instance, you can use this and there is no limitation for your case. More info can be found in Smtp.IsSmtpContext docs.

Regards,
Alex
Back to Top View Alex's Profile Search for other posts by Alex
 
Neil_Knight
Newbie
Newbie


Joined: 06 December 2011
Location: United Kingdom
Online Status: Offline
Posts: 30
Posted: 23 January 2012 at 1:15am | IP Logged Quote Neil_Knight

Hi Alex,
Thanks for your help. I'll run a new trial app to see if I can get this configured correctly.

Does the QuickSend method open a connection, send the mail message and then disconnect? Or could I open a connection via the Smtp object, use the QuickSend method and then call a Disconnect?
Back to Top View Neil_Knight's Profile Search for other posts by Neil_Knight
 
Igor
AfterLogic Support
AfterLogic Support


Joined: 24 June 2008
Location: United States
Online Status: Offline
Posts: 6104
Posted: 23 January 2012 at 2:19am | IP Logged Quote Igor

That's right, QuickSend methods performs connect and disconnect. If you're doing those operations in your code explicitly, you'll need to use Send method rather than QuickSend.

--
Regards,
Igor, AfterLogic Support
Back to Top View Igor's Profile Search for other posts by Igor
 
Neil_Knight
Newbie
Newbie


Joined: 06 December 2011
Location: United Kingdom
Online Status: Offline
Posts: 30
Posted: 23 January 2012 at 2:36am | IP Logged Quote Neil_Knight

Thanks for clearing that up.
Back to Top View Neil_Knight's Profile Search for other posts by Neil_Knight
 
Neil_Knight
Newbie
Newbie


Joined: 06 December 2011
Location: United Kingdom
Online Status: Offline
Posts: 30
Posted: 23 January 2012 at 6:28am | IP Logged Quote Neil_Knight

Ok, so I wrote a new smaller application that I thought I'd simplify the process a bit. Basically I want to do:

Smtp mailer = new Smtp();

mailer.DnsServers.AutoDetect();

// Check the Domain of the recipient and configure an Smtp Server accordingly

mailer.Connect();
mailer.Hello();

// Loop through my records
mailer.Send();

mailer.Disconnect();

However, I can't find anything that will retrieve the MX details of the recipient email address. Any pointers?
Back to Top View Neil_Knight's Profile Search for other posts by Neil_Knight
 
Neil_Knight
Newbie
Newbie


Joined: 06 December 2011
Location: United Kingdom
Online Status: Offline
Posts: 30
Posted: 23 January 2012 at 6:38am | IP Logged Quote Neil_Knight

Effectively, I want to create a "session" with the MX domain server and send multiple emails to different accounts within that domain. Is this possible?
Back to Top View Neil_Knight's Profile Search for other posts by Neil_Knight
 
Neil_Knight
Newbie
Newbie


Joined: 06 December 2011
Location: United Kingdom
Online Status: Offline
Posts: 30
Posted: 23 January 2012 at 6:46am | IP Logged Quote Neil_Knight

Actually, I think that I have found my answer. I need to use Smtp.GetMXHosts().
Back to Top View Neil_Knight's Profile Search for other posts by Neil_Knight
 
Neil_Knight
Newbie
Newbie


Joined: 06 December 2011
Location: United Kingdom
Online Status: Offline
Posts: 30
Posted: 24 January 2012 at 1:50am | IP Logged Quote Neil_Knight

Just a quick thanks to Alex and Igor for your support. I've included the little code snippet should anyone else need to do something similar:

string recipientEmail = "someemail@gmail.com";

using (Smtp mailer = new Smtp())
{
    mailer.DnsServers.AutoDetect();

    string[] mxHosts = mailer.GetMXHosts(recipientEmail.Substring(recipientEmail.IndexOf('@') + 1));

    foreach (string smtpServer in mxHosts)
        mailer.SmtpServers.Add(new SmtpServer(smtpServer));

    if (mailer.Connect())
    {
        if (mailer.Hello())
        {
            for (int i = 0; i < numOfEmails; i++)
            {
               mailer.Message = new MailMessage();
               // Configure your From, To, Subject etc.
               // with your data

               mailer.Send();
            }
        }

        mailer.Disconnect();
    }    
}
Back to Top View Neil_Knight's Profile Search for other posts by Neil_Knight
 
georgezetta
Newbie
Newbie


Joined: 28 July 2012
Online Status: Offline
Posts: 3
Posted: 16 August 2012 at 3:37am | IP Logged Quote georgezetta

How can I send multiple Links via Mail ?
Back to Top View georgezetta's Profile Search for other posts by georgezetta
 
Alex
AfterLogic Support
AfterLogic Support
Avatar

Joined: 19 November 2003
Online Status: Offline
Posts: 2206
Posted: 16 August 2012 at 4:00am | IP Logged Quote Alex

An e-mail may contain any number of links or any other text.

Regards,
Alex
Back to Top View Alex's Profile Search for other posts by Alex
 

If you wish to post a reply to this topic you must first login
If you are not already registered you must first register

  Post ReplyPost New Topic
Printable version Printable version

Forum Jump

Powered by Web Wiz Forums version 7.9
Copyright ©2001-2004 Web Wiz Guide