Laden...

SendAsyncMail userstate

Erstellt von w1z4rd2003 vor 16 Jahren Letzter Beitrag vor 16 Jahren 1.369 Views
w1z4rd2003 Themenstarter:in
624 Beiträge seit 2006
vor 16 Jahren
SendAsyncMail userstate

hallo zusammen
ich bin schon seit stunden diesen code am studieren! eigentlich ist mir alles klar aber ich verstehe nicht was der string userstate soll.
in der SendCompletedCallback funktion wird e.Cancelled und e.Error ja immer false seind da der string userstate schon fix deklariert ist!
kann mir jemand erklären was das genau soll?


using System;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Threading;
using System.ComponentModel;
namespace Examples.SmptExamples.Async
{
    public class SimpleAsynchronousExample
    {
        static bool mailSent = false;
        public static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
        {
            // Get the unique identifier for this asynchronous operation.
             String token = (string) e.UserState;
           
            if (e.Cancelled)
            {
                 Console.WriteLine("[{0}] Send canceled.", token);
            }
            if (e.Error != null)
            {
                 Console.WriteLine("[{0}] {1}", token, e.Error.ToString());
            } else
            {
                Console.WriteLine("Message sent.");
            }
            mailSent = true;
        }
        public static void Main(string[] args)
        {
            // Command line argument must the the SMTP host.
            SmtpClient client = new SmtpClient(args[0]);
            // Specify the e-mail sender.
            // Create a mailing address that includes a UTF8 character
            // in the display name.
            MailAddress from = new MailAddress("jane@contoso.com", 
               "Jane " + (char)0xD8+ " Clayton", 
            System.Text.Encoding.UTF8);
            // Set destinations for the e-mail message.
            MailAddress to = new MailAddress("ben@contoso.com");
            // Specify the message content.
            MailMessage message = new MailMessage(from, to);
            message.Body = "This is a test e-mail message sent by an application. ";
            // Include some non-ASCII characters in body and subject.
            string someArrows = new string(new char[] {'\u2190', '\u2191', '\u2192', '\u2193'});
            message.Body += Environment.NewLine + someArrows;
            message.BodyEncoding =  System.Text.Encoding.UTF8;
            message.Subject = "test message 1" + someArrows;
            message.SubjectEncoding = System.Text.Encoding.UTF8;
            // Set the method that is called back when the send operation ends.
            client.SendCompleted += new 
            SendCompletedEventHandler(SendCompletedCallback);
            // The userState can be any object that allows your callback 
            // method to identify this send operation.
            // For this example, the userToken is a string constant.
            string userState = "test message1";
            client.SendAsync(message, userState);
            Console.WriteLine("Sending message... press c to cancel mail. Press any other key to exit.");
            string answer = Console.ReadLine();
            // If the user canceled the send, and mail hasn't been sent yet,
            // then cancel the pending operation.
            if (answer.StartsWith("c") && mailSent == false)
            {
                client.SendAsyncCancel();
            }
            // Clean up.
            message.Dispose();
            Console.WriteLine("Goodbye.");
        }
    }
}

664 Beiträge seit 2005
vor 16 Jahren

Hi

userstate dient IMHO der Unterscheidung mehrerer asynchronen Methodenaufrufe.
Entsprechend gesetzt, weißt du zu welchem Aurfuf die Antwort gehört.

B
1.529 Beiträge seit 2006
vor 16 Jahren

Das Problem bei den ganzen asynchronen Methoden ist ja, dass du prinzipiell mehrere davon gleichzeitig ausführen kannst. Im Normalfall benutzen diese aber alle den gleichen Progress- bzw. Completed-Handler. Nur woher soll der Handler dann wissen, für welchen Transfer er jetzt aufgerufen wurde?
Ganz einfach: durch das beliebige Objekt, das allen async-Methoden mitgegeben werden kann. Das könnte zum Beispiel eine ID sein. In deinem Fall halt einfach ein String.

w1z4rd2003 Themenstarter:in
624 Beiträge seit 2006
vor 16 Jahren

hallo
danke erstmal für die schnellen antworten.

ich hab es aber irgendwie noch nicht so geschnallt. Also ich hab ein tool geschrieben das mehrere mails aufs mal verschickt. wenn ich debugge ruft er z.B 2 mal die methode EmailSenden() auf (für das versenden von 2 mails). Am schluss wenn diese Methode 2 mal durchgelaufen worden ist geht er in die Methode SendCompletedCallback() und durchläuft diese auch 2 mal.

im string token ist bei mir immer den string den ich in EmailSenden deklariert haben.

das erste mal passiert in der Methode SendCompletedCallback folgendes:
Im Strink token ist der String "Nachricht"
Der debugger läuft in e.Error ein (in e.Error steht MailBox unavailable usw.)

Beim zeweiten mal wird das mail richtig verschickt, d.h er läuft durch die letzte bedingung durch. Soweit ist mir alles klar, aber wo brauche ich den string "Nachricht" ist mir nicht so ganz klar.


            String token = (string)e.UserState;
            // Abgebrochen
            if (e.Cancelled)
            {
               tslHautpform.Text = "Der Vorgang wurde abgebrochen";
            }
            // Fehler
            if (e.Error != null)
            {
                tslHautpform.Text = "Es wurden nicht alle Mahnungen erfolgreich verschickt";
            }
            else
            // Erfolgreich
            {
                lbxMahnungen.Items.Add("OK");
            }
            mailsent = true;
        }

B
1.529 Beiträge seit 2006
vor 16 Jahren

Als Beispiel könnte ein Downloadmanager dienen.
Diese lädt mehrere Dateien herunter und zeigt den Fortschritt in einem ListView an. Dann könnte man beim Start des asynchronen Downloads das zugehörige ListViewItem übergeben.
Der Download-Progress-Handler kann dann einfach im "mitgelieferten" ListView den Fortschritt ausgeben, ohne wissen zu müssen, was da eigentlich getan wird.
Noch deutlicher kann ich es dann fast nicht mehr beschreiben.