Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

SOS!!! Email Sending

Îåêßíçóå áðü ôï ìÝëïò pan. Τελευταία δημοσίευση από το μέλος pan στις 07-05-2007, 16:29. Υπάρχουν 10 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  06-05-2007, 11:11 31480

    SOS!!! Email Sending

    Καλημέρα

    Θέλω την βοήθεια σας και να μου πείτε αν έχω λάθος στον κώδικα. Χρησιμοποιώ αυτήν την mini εφαρμογή σε εβδομαδιαία βάση επι 1.5 χρόνο για να στέλνω μαζικά email BCC (αλλα ενα - ενα) σε πελάτες της εταιρίας που εργαζομαι. Τα emails που φορτώνω στο listbox1 είναι μοναδικά, πολλά όμως από αυτά δεν υπάρχουν (ή εχουν γίνει expired ή έχουν full mailbox). H λίστα που στέλνω κάθε φορά είναι γύρω στις 10.000 emails. Τo queue του server χωράει άνετα πάνω από 30.000 emails. Οπως τα στέλνω δεν περιμένω να πάρω απάντηση από τον mail server επειδή έχει μεγάλο queue.

    Μέχρι τώρα δεν είχε δημιουργηθεί πρόβλημα. Συνέβη όμως τώρα. Έστειλα σε μία λίστα 5.000 πελατών και δυστυχώς κόλλησε κάτι. Το πρόγραμμα δεν τελείωσε ποτέ την loop. Το ξέρω γιατί το τελευταίο email ήταν το δικό μου στην λίστα και εγώ ποτέ δεν το έλαβα. Οπότε αναγκάστικα να το κλείσω το πρόγραμμα με το CTRL+ALT-DEL.  Δεν ξέρω αν είναι από την μεριά μου είναι το λάθος δεδομενου ότι δεν έχει ξανασυμβεί μέχρι τώρα. Πολλοί παραλήπτες έλαβαν πάνω από 100 φορές το ίδιο email. Άλλοι το έλαβαν 180, άλλοι 70, άλλοι 500 φορές το ίδιο email και άλλοι 1000 φορές !!!.

    Θα ήθελα να μου πείτε αν έχω κάνει κάτι λαθος στον κώδικα και αν μπορώ να πιάσω κάπως το exception. To λέω αυτό γιατί πολλοί προγραμματιστές μου είπαν ότι είναι λάθος όπως χειρίζομαι το exception και την εντολή Send. Εγω δοκίμασα αμέσως μετά να ξανα-τρέξω το πρόγραμμα και αντι να στέλνω το email  απλά να τυπώνω κάθε email που διαβάζω από το listbox1 σε ένα textbox form. Και η loop τελείωσε αμέσως και μου τύπωσε όλα τα email ένα ενα κανονικα. Αμέσως μετά από αυτό δοκιμάσα να στείλω 3000 email σε 5 διαφορετικά δικα μου account και επίσης τα έλαβα όλα σωστά (από μία φορά) και η loop τελείωσε αμέσως. Υπάρχει περίπτωση να κόλλησε ο SmtpClient mail server ??

    Ευχαριστώ πολύ

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    private void button1_Click(object sender, System.EventArgs e) //send newsletter
    {

    // MailAddress from = new MailAddress("[email protected]", "Ben Miller");

    MailAddress from = new MailAddress(textBox3.Text.ToString(), textBox2.Text.ToString());
    MailMessage message = new MailMessage();
    message.From = from;
    message.Subject = textBox5.Text.ToString(); // TEST
    message.IsBodyHtml = true;
    message.Body = textBox4.Text.ToString(); // HTML

    // Mou emfanizoun se dyo label posa pigan kai posa ekanan failed (aploi counter)
    int successSend = 0;
    int failemail = 0;

    SmtpClient server = new SmtpClient();
    server.Host = "xxx.xxx.xxx.xxx"; // IP tou mail server.
    server.Timeout = 3600000;

    for (int k=0; k<listBox1.Items.Count; k++)
    {
      try
      {
       MailAddress Bcc = new MailAddress(listBox1.Items[k].ToString());
       message.Bcc.Add(Bcc);
       server.Send(message);
       message.Bcc.Clear();
       successSend += 1;
       }
      catch (SmtpException ex)
      {
       failemail += 1;
      }
      finally
      {
      }
     
    }//end of for
    label7.Text += " Total Send: " + successSend.ToString();
    label8.Text += " Total Failed: " + failemail.ToString();





    } //end of button1

  •  06-05-2007, 12:28 31481 σε απάντηση της 31480

    Απ: SOS!!! Email Sending

    Αυτό μου θυμίζει πολύ ένα παρόμοιο πρόβλημα που είχα αντιμέτωπίσει κι εγώ, πρίν πολλά χρόνια, γράφοντας σε απλό ASP. Και τότε συνέβαινε ακριβώς αυτό που περιγράφεις με τον virtual SMTP του IIS, και το CDONTS.MailMessage object. Κι αν δεν κάνω λάθος, αυτή είναι η βιβλιοθήκη που χρησιμοποιεί ο SmtpClient "απο κάτω".

    Τότε ξεπεράσαμε το πρόβλημα σταματώντας να χρησιμοποιούμε CDONTS, και το γυρίσαμε σε κάποια άλλη βιβλιοθήκη. Είναι πολύ δύστροπο το CDONTS ( η για να το θέσω καλύτερα ... μάλλον .. κακομαθημένο :D )

    Καλή τύχη pak, δε σε ζηλεύω φίλε. Είναι απο τα πιο "σπαστικά" προβλήματα στον κόσμο !

    Angel
    O:]
  •  06-05-2007, 13:20 31482 σε απάντηση της 31481

    Απ: SOS!!! Email Sending

    O pak είμαι εγώ!! Ο από πάνω είναι ο pan!!!Stick out tongueStick out tongue
    View Παναγιώτης Χαραλάμπους's profile on LinkedIn
    Coding at Mediterranean Acoustics
  •  06-05-2007, 13:58 31483 σε απάντηση της 31480

    Απ: SOS!!! Email Sending

    Α) Όντως είναι πολύ λάθος ο τρόπος που χειρίζεσαι το exception! Ο κώδικάς σου, όπως είναι γραμμένος, απλά κάνει ότι δε συμβαίνει τίποτα. Δεν υπάρχει χειρότερος τρόπος να χειριστείς ένα exception! Στο catch πρέπει οπωσδήποτε να κάνεις κάτι με αυτό. Ορίστε μερικές επιλογές:

    • να το πετάξεις προς τα έξω (throw ex;) για να το πιάσει το runtime
    • να το καταγράψεις σε ένα αρχείο log
    • να το εμφανίσεις στην οθόνη (π.χ. 'This exception occured ' + ex.Message + '. Would you like to continue?')
    • ...να κάνεις κάτι τέλος πάντων με αυτό, όχι να κάνεις ότι δε συνέβει τίποτα!

    Β) Επίσης είναι λάθος να βάζεις τόσο μεγάλο timeout. Μπορεί αυτός να είναι και ο λόγος που κόλησε το πρόγραμμά σου. Το timeout, είτε είναι database connection timeout, database command timeout, smtp timeout κλπ. είναι για να κάνεις ένα πρόγραμμα να ξεκολήσει αν ένας server δεν ανταποκρίνεται, πετώντας προς τα έξω ένα timeout exception. Βάζοντας τόσο μεγάλο timeout (3600000 msec = 1 ώρα!) ουσιαστικά λες στον smtp cilent να περιμένει 1 ώρα μέχρι να ανταποκριθεί ο smtp server. Αν ο smtp server είναι κατεβασμένος ή αν ο client έχει κάποιο πρόβλημα δικτύου, τότε θα περιμένεις 1 ώρα μέχρι να το αντιληφθείς! Και λαμβάνοντας υπόψη ότι έχεις ένα loop με χιλιάδες αποστολές e-mail, θα περιμένεις 1ώρα*χιλιάδες φορές! Εφόσον ο smtp server είναι στο τοπικό δίκτυο, ένα timeout της τάξης των 30 δευτερολέπτων είναι αρκετό. Άντε το πολύ 1 λεπτό. Αλλά σε κάθε περίπτωση, αν ο server δεν ανταποκριθεί για ένα μήνυμα τότε πρέπει να εμφανίζεις το exception κάπου και να σταματάς τη διαδικασία αποστολής!

    Γ) Νομίζω κατά τα άλλα ότι εφόσον βάζεις τον αποστολέα στο πεδίο BCC (και πολύ σωστά κάνεις για μια τόσο μαζική διαδικασία αποστολής e-mail), θα πρέπει να βάζεις περισσότερους από έναν και να στέλνεις το ίδιο μήνυμα, με μιά εντολή server.send. Π.χ. θα μπορούσες να στέλνεις το μήνυμα σε 50 παραλήπτες ή 100 με ένα send. Θα μειώσεις αρκετά το χρόνο εκτέλεσης.

    Δ) Κάτι πολύ σημαντικό! Το ίδιο bug σε ένα κομμάτι κώδικα μπορεί να είναι από ασήμαντο έως και να ξεκινήσει τον τρίτο παγκόσμιο πόλεμο! Το bug που έχεις εσύ στον κώδικά σου έχει στείλει χιλιάδες λάθος e-mail σε πελάτες της εταιρείας σου. Έχει ενοχλήσει πολλούς από αυτούς, ενώ φαντάζομαι ότι το domain name της εταιρείας σου δεν είναι και ότι πιο ευχάριστο για ένα spam filter! Μπορεί να μην είναι και αφορμή για πόλεμο, αλλά είναι αρκετά σημαντικό!
     

     


    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  06-05-2007, 18:20 31488 σε απάντηση της 31480

    Απ: SOS!!! Email Sending

    Τα βάσανά σου οφείλονται στη λανθασμένη προσέγγιση του θέματος... Smile

    Ο παραπάνω κώδικας είναι μια χαρά ως proof-of-point του θέματος "στέλνω προγραμματιστικά e-mail". Από εκεί και πέρα υπάρχει αρκετός δρόμος από το proof-of-point μέχρι το line-of-business. Στο line-of-business εμπλέκονται όλα αυτά τα θέματα που αντιμετώπισες όταν σταμάτησαν τα πράγματα να πηγαίνουν μια χαρά. Πρέπει λοιπόν να σκεφτείς πως στην εφαρμογή σου, πέρα από το core ("στέλνω προγραμματιστικά e-mail") θα διασφαλίσεις ότι αν κάτι πάει στραβά αφενός θα μάθεις τι ήταν αυτό και αφετέρου αν δεν ολοκληρωθεί όλη η διαδικασία θα μπορέσεις να συνεχίσεις από εκεί που είχες μείνει.

    Στο παραπάνω πλαίσιο λοιπόν, θα πρέπει να βρεις ποιές είναι οι περιπτώσεις να λάβεις exception κατά το Mail.Send() και τι θα συμβαίνει σε κάθε μία από αυτή. Υποθέτω θα πρέπει να καταγράφονται τα πάντα σε κάποιο log, ωστόσο πέρα από αυτό, πιθανώς κάποια exceptions να πρέπει να τερματίζουν τη διαδικασία και κάποια άλλα να κάνουν retry. Επιπρόσθετα, θα πρέπει να εγκαταλείψεις το "στέλνω e-mail σε όλους όσους είναι στο listbox" και να υλοποιήσεις μία λογική του τύπου "στέλνω e-mail σε όσους είναι στον πίνακα Χ, σε batches των 100 και μόλις τελειώσει κάθε batch, ενημερώνω τη βάση για τις διευθύνσεις που έφυγε το e-mail". Έτσι θα μπορείς κάθε φορά όταν ζητάς τις διευθύνσεις να προσθέσεις ένα φίλτρο για να μην πάρεις και αυτές στις οποίες έχεις στείλει ήδη e-mail.


    Vir prudens non contra ventum mingit
  •  07-05-2007, 13:35 31526 σε απάντηση της 31488

    Απ: SOS!!! Email Sending

    Ευχαριστώ για τις προτάσεις σας. Επειδή δεν έχω μεγάλη ευχέρεια με τα try-catch-finally. Εφτιαξα το παρακάτω. Είναι αρκετό ώστε να αποφύγω όλα τα μπερδέματα ??

    Στην πραγματικότητα ανοίγω ένα αρχείο που γράφω σαν log οτιδηποτε γίνεται. Αν πάει καλά το email γράφετε στο αρχείο. Δεν θέλω να χρησιμοποιήσω βάση ουτε να να στείλω μαζικά ανα 50 ή 100 τα emails. Αν κάτι στραβώσει, έχω προσθέσει 2 διαφορετικά exceptions, όπου καταγράφω στο αρχείο οτι και αν συμβεί και στο finally τσεκάρω και αναλόγως κάνω Exit από την εφαρμογή.

     

    Ευχαριστώ Πολύ

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     for (int k = 0; k < listBox1.Items.Count; k++)
    {
    try
    {
    MailAddress Bcc = new MailAddress(listBox1.Items[k].ToString());
    message.Bcc.Add(Bcc);
    server.Send(message);
    sw.WriteLine(Bcc);
    message.Bcc.Clear();
    successSend += 1;
    fff = 0;
    }
    catch (SmtpException ex)
    {
    failemail += 1;
    logException = "SMTP= " + listBox1.Items[k].ToString() + " // " + ex.Message.ToString();
    sw.WriteLine(logException);
    fff = 1;
    throw ex;
    }
    catch (Exception ex2)
    {
    failemail += 1;
    logException = "EXCP= " + listBox1.Items[k].ToString() + " // " + ex2.Message.ToString();
    sw.WriteLine(logException);
    fff = 1;
    throw ex2;
    }
    finally
    {
    if (fff != 0) { Application.Exit(); }
    }

    }//end of for

     

  •  07-05-2007, 13:54 31527 σε απάντηση της 31526

    Απ: SOS!!! Email Sending

    Εδώ μπορείς να διαβάσεις κάποια πράγματα για τη διαχείριση exceptions στο .NET. Είναι ένα αρκετά παλιό έγγραφο το οποίο όμως θυμάμαι ότι ήταν πολύ κατατοπιστικό όταν είχα ξεκινήσει να ασχολούμαι με το .NET: Microsoft Patterns & Practices - Exception Management Architecture Guide

    Κατά τα άλλα ρίξε και μια ματιά στην try/catch στο MSDN documentation και θα καταλάβεις πως χρησιμοποιείται.

    Το SmtpException κληρονομεί το Exception και φέρει μαζί του κάποια επιπλέον πληροφορία. Εφόσον δεν την χρησιμοποιείς, δε χρειάζεται να κάνεις catch και το SmtpException και το Exception. Αρκεί μόνο το δεύτερο.

    Επίσης, εφόσον σταματάς τη διαδικασία όταν συμβεί ένα exception, μπορείς πολύ εύκολα να το εμφανίσεις και σε ένα message box. Έτσι ώστε ο χειριστής θα δει το πρόβλημα χωρίς να ανατρέξει στο αρχείο. Το αρχείο μπορείς να κρατήσεις για ιστορικούς λόγους. 

    Γενικά χρησιμοποίησε καλύτερα ονόματα μεταβλητών, ακόμα και για ένα τόσο μικρό πρόγραμμα. Το όνομα fff δεν βοηθάει κανένα.


    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  07-05-2007, 14:06 31528 σε απάντηση της 31527

    Απ: SOS!!! Email Sending

    A μάλιστα! Τώρα κατάλαβα. 10000 ευχαριστώ
  •  07-05-2007, 14:22 31530 σε απάντηση της 31528

    Απ: SOS!!! Email Sending

    Ωστόσο, όταν συμβεί το λάθος η διαδικασία αυτή δεν μπορεί να συνεχιστεί από εκεί που σταμάτησε. Όσοι έχουν λάβει e-mail επιτυχώς, θα ξαναλάβουν.


    Vir prudens non contra ventum mingit
  •  07-05-2007, 16:22 31544 σε απάντηση της 31530

    Απ: SOS!!! Email Sending

    KelMan:

    Ωστόσο, όταν συμβεί το λάθος η διαδικασία αυτή δεν μπορεί να συνεχιστεί από εκεί που σταμάτησε. Όσοι έχουν λάβει e-mail επιτυχώς, θα ξαναλάβουν.

    Συμφωνώ και επαυξάνω. Πρέπει να έχεις διαδικασία επαναποστολής των email Που δεν στάλθηκαν.

    Να σαι δω τι θα κάμεις σε καμία αναβάθμιση του Exchange...Tongue Tied αν δεν έχεις διαδικασία επαναποστολής.

    Η λύση του πίνακα κουβά στη βάση για εμένα είναι η καλύτερη. 

     


    Manos
  •  07-05-2007, 16:29 31547 σε απάντηση της 31530

    Απ: SOS!!! Email Sending

    μα θα ανοίξω το log αρχείο θα δω που σταμάτησε σε ποια εγγραφή δηλ και απο κει και πέρα θα συνεχίσω. Μόνο εγώ την (θα) τρέχω την εφαρμογή. Με χρήση βάσης καταλαβαίνω απόλυτα ότι αποφεύγω όλην αυτήν την περιττή διαδικασία(άνοιγμα - κλείσιμο αρχείου - ξαναφόρτωμα νέου αρχείου) και είναι η πιο σωστή λύση αλλά στην παρούσα φάση δυστυχώς δεν γίνεται να υλοποιηθεί με αυτόν τον τρόπο.

     

Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems