David Kornitz
Guest
|
Posted:
Sat Nov 27, 2004 11:03 pm Post subject:
Creating a multi-threaded C# OnArrival SMTP Sink |
|
|
Goal: Write C# managed sink against the SMTP OnSubmission event. Compare
recipient list against known "good" list and remove invalid recipients.
Make it multi-threaded so multiple messages can be processes simultaneously.
Problem: I don't know how to convert my working sample code from
Non-threaded to multi-threaded. Below is the applicable code:
using System;
using System.Threading;
using System.Data.SqlClient;
using System.Runtime.InteropServices;
using Microsoft.Exchange.Transport.EventInterop;
namespace SmtpRecipientFilter
{
[Guid("2BE22109-14D6-4d13-A8FE-795E2233DABD")]
public class InboundSink : IMailTransportSubmission, IEventIsCacheable
{
MailMsg emailMessage;
public InboundSink()
{
// Constructor
}
void IEventIsCacheable.IsCacheable()
{
// T8his will return S_OK by default.
}
void IMailTransportSubmission.OnMessageSubmission
(MailMsg message, IMailTransportNotify ntf, IntPtr ptr)
{
emailMessage = message;
processMessage();
}
/// Compare the recipient list against a known good list of email
/// addresses and process accordingly.
private void processMessage()
{
MessageProcessor mp = new MessageProcessor();
mp.EmailMessage = emailMessage;
mp.ValidateRecipientList();
mp = null;
}
}
}
The MessageProcessor class looks like this:
using System;
using System.Collections.Specialized;
using Microsoft.Exchange.Transport.EventInterop;
using Microsoft.Exchange.Transport.EventWrappers;
namespace SmtpRecipientFilter
{
public class MessageProcessor
{
private MailMsg emailMessage;
public MessageProcessor()
{
// Constructor
}
/// Compare the recipient list of the EmailMessage to the known good
/// list of email addresses. Remove invalid recipients from the email ///
message and log to a file for later analysis.
public void ValidateRecipientList()
{
// Get the list of valid email addresses that the recipient list will be
// compared against.
StringDictionary sdEmailList = DataLayer.GetValidEmailAddresses();
Message msg = new Message(emailMessage);
int numRecips = (int) msg.Recips.Count;
RecipsAdd newRecips = msg.AllocNewList();
string recipEmailAddress;
for (uint i = 0; i < numRecips; i++)
{
recipEmailAddress = msg.Recips[i].SMTPAddress;
if (sdEmailList.ContainsKey(recipEmailAddress))
{
newRecips.AddSMTPRecipient(recipEmailAddress);
}
}
msg.WriteList(newRecips);
msg = null;
}
public MailMsg EmailMessage
{
get
{
return emailMessage;
}
set
{
emailMessage = value;
}
}
}
}
The code works correctly in a non-threaded mode, when I add the lines below,
in an attempt to convert to a threaded applicaiton, the "mp.EmailMessage =
emailMessage;" [emailMessage] does not contain any information (or is null)
and therefore it throws a "System.NullReferenceException". I'm using the
same message when testing the code.
Thread synchThread = new Thread(new ThreadStart(processMessage));
synchThread.Priority = ThreadPriority.Lowest;
synchThread.Start();
The "System.NullReferenceException" occurs at the following line.
recipEmailAddress = msg.Recips[i].SMTPAddress;
Any help would be greatly appreciated.
Thanks in advance.
|
|