|
The solution I found most elegant had already been posted by David1984 but is deleted. So I'm going to post it now:
You want a number X that can be divided by 5.
Any number Y can be multiplied by 5. The result X is divisible by definition (and by 5).
You want X to have 5 digits.
5-digit-numbers range from 10000 to 99999. Divide both by 5 and throw away the result's decimal places to get the limits for Y (2000 to 19999).
Supposed you already have an instance of Random obeying the tips on its use, you get X by using this code (X changed to a meaningful name)
int randomDivisibleByFive = random.Next(2000, 19999) * 5;
Ciao,
luker
|
|
|
|
|
Hey guys, I'm just looking for someone to point me in the right direction here, not necessarily provide a solution..
I have been tasked with writing a lightweight program for sending out email newsletters. This in itself has been easy enough to do.. but obviously I want to be able to send to as many recipients as fast as is possible.
At the moment my solution sends 1 email at a time (the to address is provided by a stored procedure that returns 1 at a time), but this is a little slow.
Having looked into it a little bit, I know I can send up to 5 emails concurrently using my smtp server before they start being throttled, and that I should be recycling the connections rather than creating and dropping them each time. I have been trying to get my head round the problem and seem to have a mental block as to the best way to create these new connections and recycle them.
Some pointers would be great if anyone can advise.
Thank you!
|
|
|
|
|
markymark82 wrote: Having looked into it a little bit, I know I can send up to 5 emails concurrently using my smtp server before they start being throttled, and that I should be recycling the connections rather than creating and dropping them each time.
Huh?
Did you write your own email class rather than using the one already in .Net?
Presumably the answer is yes since otherwise the question makes no sense.
If you did then normally it is going to be marginally faster to keep the connection rather than creating it each time in terms of network traffic. However as you seem to have already determined the server itself can impact this.
Exactly what sort of volume do you anticipate because if it is a small volume then it shouldn't matter how fast you are going. If a large volume then I wonder why your company doesn't just adjust the smtp server to be more accommodating for this required business task.
|
|
|
|
|
I'm using the System.Net.Mail class, so it's entirely likely my question doesn't make sense.
The sort of volume it could have to handle is up to around 80k messages + more as the list grows.
Each email is customised to the address with individual tracking strings on the URLs etc. hence being provided 1 at a time from a stored procedure.
Unfortunately, we are using authsmtp as our smtp server for improved deliverability, hence the limit to 5 connections at a time, and that can't be changed.
I have observed that actually recycling the connections gives a very minimal speed improvement, so I'm prepared to overlook that if need be, but I'm unsure of how to restrict the number of smtp connections open at any 1 time, waiting to send the next email until the number of open connections drops to fewer than 5 again.
I'm sure it must be fairly simple, and that I'm missing a key point somewhere, but as yet I've not found it. What has already been written for this task, initially started as a test, but it proved suitable for sending the few emails that it needed to, giving us the flexibility we needed, however, now that people have seen that it can be useful, they want to use it for higher volumes, so now I need to look at changing it and getting it right.
Thanks for the reply ![Smile | :)](https://codeproject.global.ssl.fastly.net/script/Forums/Images/smiley_smile.gif)
|
|
|
|
|
A ThreadPool should be able to do this, I think. If not, you can write a custom queue processor that holds five connections and pulls items off the queue into each one when it becomes idle. For 80,000 messages you can just push them all into the queue at the start.
|
|
|
|
|
It's funny you should start with that, I was just looking at the possibility of Threading & ThreadPools, but that's not something I've ever dealt with, as I'm really a web developer. This is my first attempt at writing a winforms app and I think I've jumped in at the deep end! I guess it's going to be a steep learning curve from here on!
At least someone else has confirmed one of the ideas I've had for it
Thank you!
|
|
|
|
|
markymark82 wrote: I have observed that actually recycling the connections
Far as I know there is no way to do that with SmtpClient. That class uses an internal connection pool.
markymark82 wrote:
The sort of volume it could have to handle is up to around 80k messages + more as the list grows.
Volume/seconds gives the rate.
So 100,000/1 second gives 27 hours.
To make that smaller you have to change the numbers.
Reduce the total number. Reduce the send time (processing or connections)
markymark82 wrote: they want to use it for higher volumes
Simple math - there is going to be an absolute limit to how fast you can send with 5 connections.
You can profile your code. That should insure that you are at least using the connections as fast as they are available. After that the only improvement is by using more connections (up to the point where you saturate some part of the network or reach a processing bottleneck.)
You can simulate what you can actually do by setting up your own SMTP pseudo server to test with. All it should do is access the email (it doesn't send it anywhere.)
markymark82 wrote: Unfortunately, we are using authsmtp
If they want to send more then the company is going to need to pay for a different solution. Certainly looks like that authsmtp can be negotiated with. There are other providers.
|
|
|
|
|
Please tell me what this silverlight warning message means.
Warning 1 For security reasons DTD is prohibited in this XML document. To enable DTD processing set the DtdProcessing property on XmlReaderSettings to Parse
and pass the settings into XmlReader.Create method.
What do I do to fix this issue?
|
|
|
|
|
The error with DTD prohibited usually appears as a result of report processing/rendering running out of memory
Reference[^]
|
|
|
|
|
Hi there!
I´m developing an application to manage financial Data, but now I need it to open several connection threads from the same WinForm called several times.
I´m triying to call Application.Run (new formPpal) several times from the static void Main(), but it doesn´t create the new form until the current one is closed.
any ideas?
Thank you! ![Wink | ;)](https://codeproject.global.ssl.fastly.net/script/Forums/Images/smiley_wink.gif)
|
|
|
|
|
You can do something like this:
for (int i = 0; i <= 3; i++)
{
FormPpal form = new FormPPal();
form.Show();
}
Application.Run();
Hope this helps
...and I have extensive experience writing computer code, including OIC, BTW, BRB, IMHO, LMAO, ROFL, TTYL.....
|
|
|
|
|
Application.Run is used to start a message loop on the current thread. To show multiple forms, you must use the Show method of the Form class. You can do it from the Main method like this:
Form2 f2 = new Form2();
f2.Show();
Form3 f3 = new Form3();
f3.Show();
Form1 f1 = new Form1();
Application.Run(f1);
But as soon as your instance of Form1 is closed, the application will exit.
EDIT: Made some changes as suggested by BillWoddruff and Luc Pattyn.
"Don't confuse experts with facts" - Eric_V
modified on Monday, August 22, 2011 9:58 AM
|
|
|
|
|
The code in your example below the invocation of Application.Run(new Form1()); will never be executed.
Try it and see.
best, Bill
"In the River of Delights, Panic has not failed me." Jorge Luis Borges
|
|
|
|
|
yes, it will run as soon as Form1 gets closed; however the other Forms (also) being modeless, the main code will run to completion immediately after creating those Forms, so you probably will never actually see them. Try adding a MessageBox.Show inside the Form2 constructor!
|
|
|
|
|
Nice, +5
"Don't confuse experts with facts" - Eric_V
|
|
|
|
|
Good point, Luc: perhaps I should have said: "after the termination of the Application.Run(SomeForm) process, while, technically, the code that follows will be kind-of executed, the programmer who believes this is useful, in some practical way, needs medication for stress immediately." ?
As long as we're cataloging horrors: this will actually work:
Application.Run(new Form1());
Form1 f3 = new Form1();
f3.Text = "BAD PROGRAMMING STYLE INCARNATE";
Application.Run(f3);
Yup, when Form1 is closed, a new Windows Message Pump is instantiated, and Form 'f3 has its day in the sun.
Again, a pointless exercise: after all: all 'state' created in the first Form's life-cycle is gone when it is closed.
best, Bill
"In the River of Delights, Panic has not failed me." Jorge Luis Borges
modified on Tuesday, August 23, 2011 2:36 AM
|
|
|
|
|
I'm afraid I can't agree once more.
public static void Main() {
Application.Run(new Form1());
Application.Run(new Form2());
}
makes perfect sense to me, it will show and run Form2 once you're done with Form1; there may be no need to share state between those Forms, or there may be some mechanism that shares that state, maybe additional data structures in the class that holds such Main() method, maybe in some other global or singleton class, maybe in a database, you name it.
A simple example could be: Form2 is the actual application, Form1 is a complex license dialog which connects to a license server, interacts with the user, asks for a new license key, etc. When the license fails, it calls Application.Exit(), preventing Form2 to even get constructed, hence being safer than a dialog shown by Form2's constructor or Load event.
|
|
|
|
|
Correct, my +5 . I failed to realise that, thanks for pointing out. But again even if you show the other forms before calling Application.Run() with the main form, the application ends as soon as the main form closes. And if you show all forms using its Show method and call Application.Run() without arguments, the app keeps running in the background even if all the forms are closed (unless, of course, you call Application.Exit() )
"Don't confuse experts with facts" - Eric_V
|
|
|
|
|
Shameel wrote: And if you show all forms using its Show method and call Application.Run() without arguments, the app keeps running in the background even if all the forms are closed (unless, of course, you call Application.Exit() ) Hi Shameel,
Right you are, and in my bottom-most top-level response to this thread, I indicated a simple strategy to handle that potential case of the "formless application." Let me run it by you again:
1. for each Form you launch, insert an EventHandler for the Form.Closing event.
2. in that handler check if the Application.OpenForms.Count == 1: if so, call Application.Exit.
It's a strategy I have used many times; I think of it as a variant of the so-called SDI pattern multiple-form WinForm architecture as described by Chris Sells, and others.
best, Bill
"In the River of Delights, Panic has not failed me." Jorge Luis Borges
|
|
|
|
|
Thank you both guys, but there is a problem with this solution.
Since Application.Run() operates with the same thread, it is not able to discriminate which is the form that is being used by user (buttons, data, client_id...)
But I think that must be re-coded by me...
Regards,
D.
|
|
|
|
|
You can certainly keep track of what Form is Active:
For example:
1. Create a static public class in which you have a variable of type Form named TheActiveForm
2. Write event handlers for the Activated and Deactivate Events of all your Forms and have them update the static variable 'TheActiveForm.'
If you wish you can turn that static class into a complete event-handler that accepts and forwards messages from Form to Form, etc.
Please note that my saying you 'can' do this doesn't mean 'doing this' is right for your particular solution.
best, Bill
"In the River of Delights, Panic has not failed me." Jorge Luis Borges
|
|
|
|
|
I mean, Application.Run() has 3 overloads, one of them is Application.Run(Form mainForm).
I want to call it simultaneously as many forms as I´ve opened before, but the problem is that Application.Run cannot be multiple-called.
I hope it´s clear enough what I need and someone can help me.
Ty,
D.
|
|
|
|
|
An application can have only one main UI thread at a time, your main form. To open other forms you need to use Show or ShowDialog if they are modal. You can do this in the load event of the main form.
I know the language. I've read a book. - _Madmatt
"The OP herself was not sure about her question"
"The OP is from India and I know what she meant." - Shameel
|
|
|
|
|
Thanks Mark ![Wink | ;)](https://codeproject.freetls.fastly.net/script/Forums/Images/smiley_wink.gif)
|
|
|
|
|
Your scenario I find a little ambiguous: you write, on the one hand, about connection threads on the same WinForm, but, then you write of having multiple Forms: can you clarify that a bit ?
In any case you don't want to be calling Application.Run more than once.
If you are describing a scenario in which there isn't the typical pattern of a single new instance of some Form passed as the argument to Application.Run(new MainForm), and you 'Show a bunch of forms before calling Application.Run():
If that is your goal, there's nothing wrong with that: but you then need to consider the implications of that strategy:
1. there's no single Form which, when closed, will close all the other open Forms and exit the Application: you could possibly, by closing all open Forms, leave the Application running without you having any way to access it, or terminate it.
An easy work-around for the problem of closing the Application in this scenario is to write a handler for each Form's 'Closing' event, check and see if the collection of open forms in Application.OpenForms.Count == 1, and if that's the case, do an Application.Exit().
A question: what reason do you have for not creating other forms inside a MainForm launched in the usual way ?
best, Bill
"In the River of Delights, Panic has not failed me." Jorge Luis Borges
modified on Tuesday, August 23, 2011 2:38 AM
|
|
|
|
|