Yeah, this bug was spotted by another user also. Also, in this version smtp logging is turned on, so that could eventually lead to the disk being filled up by the Smtp log file. I will have to create and upload another .01.09 incremental release to fix this.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
D'oh, just downloaded your most recent code drop, Ian (.01.09.4) and it looks like it's still got some craziness in MailMessage.ToString. Line 449 of MailMessage.cs has a line that has a r\n when it should really have a \r\n. The effect of this is that all of the message headers are placed in the body of the message (because the letter 'r' is inserted in the body instead of a CRLF). I did test and verified that inserting the missing backslash fixes the problem.
On the subject of another thread, I agree that a great next step for this would be to send mail on a separate thread. This is quite simple to do in .NET (I've done something like it for another project). I'd be willing to help out with it if you like.
Also, I was thinking it might be nice for the component to raise events corresponding to the items that are currently being put into the log file. That way you could inspect what's going on in the client as it happens instead of looking at the text file after the face. I've seen other Smtp components do this and it really goes a long way toward uncovering problems. I can also help with this if you like, just let me know.
Jeffrey
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
My Bad, that was bad quality control on my part. That bug was spotted and supposed to be fixed in 01.09.4 but I dropped the ball. I'll add it to the next release. The next release will also have events like you and others have asked for.
Can you send me an example of how to send mail on another thread? I think this would be useful.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'll do you one better -- I'll write the code. (It's not perfect -- I don't pretend to be Mister .NET threading guy -- but it's start, at any rate.)
I modified the Smtp class to include a new internal variable called _msg of type MailMessage. Next I gutted SendMail() and moved its contents to a new private subroutine called SendMailThread. The new SendMail stores its input (msg) in the internal variable _msg, kicks off a thread, and causes the thread to call SendMailThread. (You have to do it this way because procedures that are called on a separate thread can't take any arguments.) So rather than referring to a msg object passed to it as an argument, SendMailThread refers to _msg.
This appears to work (it serves our objective of getting rid of the the five and a half second blocking call in Smtp.SendMail -- control now returns to the client in a matter of milliseconds). However, as is often the case with threading I/O, we have a few resource contention issues to deal with now. The first one I noticed was with the Log class -- sending mail in a rapid-fire fashion causes an exception as multiple threads attempt to access the log file simultaneously. I suspect there might be other areas of resource contention as well, but we'll have to test this more thoroughly.
I'm hoping that somebody who has more experience with threading (in C# or any other language) can jump in here with some guidance? The .NET docs seem to focus on making asynch/threaded calls over HTTP and don't seem to have much on rolling your own I/O using sockets.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hey Ian,
I ran across another bug as well as a compiler warning. I had some time so I went ahead and figured out what was going on and fixed it.
In the recent release, MailMessage.ToString puts a CRLF after the body in the final call to the StringBuilder's Append method, like so:
sb.Append(body + "\r\n");
This CRLF should be added *before* the body, like this:
sb.Append("\r\n" + body);
Doing this avoids some munging of headers wtih email body I've been experiencing with 1.09.03.
Also, this isn't a big deal, but because ToString is an override, its signature should look like this to avoid the compiler warning:
override public string ToString()
Jeffrey
Yeah, this bug was spotted by another user also. Also, in this version smtp logging is turned on, so that could eventually lead to the disk being filled up by the Smtp log file. I will have to create and upload another .01.09 incremental release to fix this.
OK, that was a different error. I fixed it in the latest release and will upload it later.
D'oh, just downloaded your most recent code drop, Ian (.01.09.4) and it looks like it's still got some craziness in MailMessage.ToString. Line 449 of MailMessage.cs has a line that has a r\n when it should really have a \r\n. The effect of this is that all of the message headers are placed in the body of the message (because the letter 'r' is inserted in the body instead of a CRLF). I did test and verified that inserting the missing backslash fixes the problem.
On the subject of another thread, I agree that a great next step for this would be to send mail on a separate thread. This is quite simple to do in .NET (I've done something like it for another project). I'd be willing to help out with it if you like.
Also, I was thinking it might be nice for the component to raise events corresponding to the items that are currently being put into the log file. That way you could inspect what's going on in the client as it happens instead of looking at the text file after the face. I've seen other Smtp components do this and it really goes a long way toward uncovering problems. I can also help with this if you like, just let me know.
Jeffrey
My Bad, that was bad quality control on my part. That bug was spotted and supposed to be fixed in 01.09.4 but I dropped the ball. I'll add it to the next release. The next release will also have events like you and others have asked for.
Can you send me an example of how to send mail on another thread? I think this would be useful.
I'll do you one better -- I'll write the code. (It's not perfect -- I don't pretend to be Mister .NET threading guy -- but it's start, at any rate.)
I modified the Smtp class to include a new internal variable called _msg of type MailMessage. Next I gutted SendMail() and moved its contents to a new private subroutine called SendMailThread. The new SendMail stores its input (msg) in the internal variable _msg, kicks off a thread, and causes the thread to call SendMailThread. (You have to do it this way because procedures that are called on a separate thread can't take any arguments.) So rather than referring to a msg object passed to it as an argument, SendMailThread refers to _msg.
This appears to work (it serves our objective of getting rid of the the five and a half second blocking call in Smtp.SendMail -- control now returns to the client in a matter of milliseconds). However, as is often the case with threading I/O, we have a few resource contention issues to deal with now. The first one I noticed was with the Log class -- sending mail in a rapid-fire fashion causes an exception as multiple threads attempt to access the log file simultaneously. I suspect there might be other areas of resource contention as well, but we'll have to test this more thoroughly.
I'm hoping that somebody who has more experience with threading (in C# or any other language) can jump in here with some guidance? The .NET docs seem to focus on making asynch/threaded calls over HTTP and don't seem to have much on rolling your own I/O using sockets.