Search The ForumSearch   RegisterRegister  LoginLogin

MailBee.NET Objects

 AfterLogic Forum : MailBee.NET Objects
Subject Topic: Issues with Smtp.Logger Post ReplyPost New Topic
Author
Message << Prev Topic | Next Topic >>
Snoogz
Newbie
Newbie


Joined: 07 March 2016
Location: United States
Online Status: Offline
Posts: 4
Posted: 24 October 2017 at 3:05pm | IP Logged Quote Snoogz

Hello,

I'm having an issue with the implementation of the SMTP Logger object, specifically I'm having an issue with using the in-memory logging while inside a C# parallel foreach.

My application calls SMTP.SendEmail() for each email object in a collection of emails, in parallel. We set smtp.Log.MemoryLog = true, and setup an event for smtp.LogNewEntry (for formatting reasons) to append each log to a string object. Then we save the return object in the database, which should contain the smtp logs for just that email. However what we're seeing is that the Logger object is shared across all the threads, which is causing our logs to be a jumbled up mess of smtp logs from all emails in that collection. Even using Logger.SyncRoot did not create suitable log output. Code snippets below.

Is there a thread safe way to implement in-memory logging? Or a way I can implement so that each email log only contains the smtp logs for its' email?

Workflow.cs
Parallel.ForEach(emails, (email) => {
      // Call to email service layer
      var result = emailSerivce.SendEmail(email);
});

EmailService.cs
public string log = "";
public Object SendEmail(Email email)
{
      Smtp smtp = new Smtp();
      smtp.Log.Enabled = true;
      smtp.Log.MemoryLog = true;
      smtp.Log.Format = MailBee.LogFormatOptions.AddDate;
      smtp.LogNewEntry += SmtpOnLogNewEntry;
...
}
private void SmtpOnLogNewEntry(object sender, LogNewEntryEventArgs e)
{
log += string.Forat("{0} {1} {2}\n",e.NewEntry.Time, e.NewEntry.MessageType, e.NewEntry.MessageText);
}

Thank you
Back to Top View Snoogz's Profile Search for other posts by Snoogz
 
Alex
AfterLogic Support
AfterLogic Support
Avatar

Joined: 19 November 2003
Online Status: Offline
Posts: 2206
Posted: 25 October 2017 at 3:05am | IP Logged Quote Alex

Hi,

Logger is unique per thread. However, your 'log' variable is not. It's shared among all the threads (and thus it ends up containing log records from all the threads). What's the purpose of this variable?

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: 25 October 2017 at 3:08am | IP Logged Quote Alex

More exactly, Logger is unique per Smtp instance. But because you're using one Smtp instance per thread, the result is just the same.

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


Joined: 07 March 2016
Location: United States
Online Status: Offline
Posts: 4
Posted: 25 October 2017 at 11:20am | IP Logged Quote Snoogz

The purpose of the log variable is to keep a string copy of the formatted logs until the process has completed then return that string to the calling process to be saved in our database. It's a global variable because I couldn't see a different implementation of saving the formatted log entries.
Back to Top View Snoogz's Profile Search for other posts by Snoogz
 
Alex
AfterLogic Support
AfterLogic Support
Avatar

Joined: 19 November 2003
Online Status: Offline
Posts: 2206
Posted: 25 October 2017 at 12:18pm | IP Logged Quote Alex

So your issue is actually not related to MailBee? You have code with many threads which all write into the same variable ('log'). So why are you asking why this happens (that all sessions from all threads write into the same variable) because that's what you're exactly doing? I don't get it..

If you need each session to be maintained separately, you obviously need to have separate 'log' variable for each thread (Smtp instance).

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


Joined: 07 March 2016
Location: United States
Online Status: Offline
Posts: 4
Posted: 26 October 2017 at 1:26pm | IP Logged Quote Snoogz

You're correct. I was getting hung up on the existing implementation of our email services and how to implement the MailBee logging. Moving the logic inside the parallel foreach and containing my objects in a ConcurrentQueue gave me the results I was looking for.

Parallel.ForEach(emailQueue, email =>
{
      string log = "";
      Smtp mailer = new Smtp();
      mailer.Log.Enabled = true;
      mailer.Log.MemoryLog = true;
      mailer.LogNewEntry += (sender, args) =>
      {
            log += "Formatted logs Here";
      }
      ...
      mailer.Send();
      email.Log = log;
}

Thanks for the clarification.
Back to Top View Snoogz's Profile Search for other posts by Snoogz
 

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