سؤال

أحاول كتابة خدمة إعلام (لأغراض غير مرغوب فيها غير مرغوب فيه بالكامل) باستخدام SMTPClient. في البداية أنا فقط حلقت من خلال كل رسالة وأرسلتها، ولكن هذا بطيء وأود تحسين السرعة. لذلك، قمت بتسجيلها لاستخدام "SENDAYNC"، ولكن الآن احصل على الخطأ التالي في المكالمة الثانية:

An asynchronous call is already in progress. 

قرأت هذا يعني أن MS CRIPPLED SYSTEM.NET.MAIL لمنع Mass-Mailers. هل هذا صحيح؟ إذا كان الأمر كذلك، فهل هناك طريقة أفضل للقيام بذلك في .NET، ولا تزال قادرا على تسجيل نتائج كل بريد إلكتروني (وهو أمر مهم لعملائنا). إذا لم يكن الأمر كذلك، فلماذا يتم استدعاء SendAsync مرة واحدة فقط؟

هل كانت مفيدة؟

المحلول

بحسب ال توثيق:

بعد استدعاء SENDAYNNC، يجب عليك الانتظار لإكمال إرسال البريد الإلكتروني قبل محاولة إرسال رسالة بريد إلكتروني أخرى باستخدام إرسال أو SendAsync.

إذن إرسال رسائل بريدية متعددة في نفس الوقت تحتاج إلى مثيلات SMTPClient متعددة.

نصائح أخرى

قد تكون قادرا على استخدام ما يلي:

ThreadPool.QueueUserWorkItem(state => client.Send(msg));

يجب أن يسمح هذا في قائمة الانتظار ورسلتها كمحيات متاحة.

من الواضح أن هذه ليست محاولة لإيقاف الارسال الجماعي.

السبب هو أن فئة SMTPClient ليست آمنة الخيط. إذا كنت ترغب في إرسال رسائل بريد إلكتروني متعددة في وقت واحد، فعليك تفرخ عدد قليل من مؤشرات الترابط العامل (هناك عدة طرق للقيام بذلك في .NET Framework) وإنشاء مثيلات منفصلة من SMTPClient في كل منها.

أعتقد أنك تسيء فهم XXXAsync فئة الأساليب. الغرض من هذه المكالمات غير المتزامنة هو السماح للبرنامج بالمتابعة، دون الحاجة إلى الطريقة لإنهاء المعالجة والعودة أولا. يمكنك بعد ذلك متابعة النتيجة في وقت لاحق من خلال الاشتراك في شيء مثل XXXReceived حدث الكائن.

لإرسال أكثر من بريد واحد في وقت واحد، قد تفكر في استخدام المزيد Threadس.

يمكنك فقط إرسال واحدة في وقت واحد لكل عميل SMTP. إذا كنت ترغب في جعل أكثر من إرسال مكالمة واحدة، فقم بإنشاء أكثر من عميل SMTP واحد.

HTH،

كولبي أفريقيا

كما لوحظ من قبل الجميع هنا، يمكنك فقط إرسال بريد إلكتروني واحد فقط في كل مرة، ولكن الطريقة لإرسال آخر مرة واحدة تم إرسالها الأولى تم إرسالها في التعامل مع الحدث .sendcompleted من فئة SMTPClient، ثم انتقل إلى البريد الإلكتروني التالي و إرسال ذلك.

إذا كنت ترغب في إرسال العديد من رسائل البريد الإلكتروني في وقت واحد، فما قال الآخرون، استخدم كائنات SMTPClient متعددة.

هناك سبب لإعادة استخدام SMTPClient., ، فإنه يحد من # الاتصالات إلى خادم SMTP. لا أستطيع إرساء فئة جديدة SMTPClient. فئة لكل مؤشر ترابط يمكن أن تقوم التقارير ببناء أو خادم SMTP بضغط مع الكثير من الاتصالات. هذا هو الحل الذي توصلت إليه عندما لم أتمكن من العثور على إجابة هنا.

انتهى بي الأمر باستخدام Autoresetevent. للحفاظ على كل شيء في المزامنة. بهذه الطريقة، يمكنني الاستمرار في الاتصال بي sendaync. في كل مؤشر ترابط، ولكن انتظر ذلك لمعالجة البريد الإلكتروني واستخدام sendcomplete. الحدث لإعادة ضبطه حتى يستمر المرء التالي.

أقوم بإعداد حدث إعادة تعيين السيارات.

        AutoResetEvent _autoResetEvent = new AutoResetEvent(true);

أقوم بإعداد عميل SMTP المشترك عند إنشاء فئتي.

        _smtpServer = new SmtpClient(_mailServer);
        _smtpServer.Port = Convert.ToInt32(_mailPort);
        _smtpServer.UseDefaultCredentials = false;
        _smtpServer.Credentials = new System.Net.NetworkCredential(_mailUser, _mailPassword);
        _smtpServer.EnableSsl = true;
        _smtpServer.SendCompleted += SmtpServer_SendCompleted;

ثم عندما أسمي إرسال ASYNC، أنتظر الحدث مسحها، ثم أرسل واحد التالي.

        _autoResetEvent.WaitOne();
        _smtpServer.SendAsync(mail, mail);
        mailWaiting++;

يمكنني استخدام SMTPClient Sendcomplete الحدث لإعادة تعيين التشغيل التلقائي حتى يرسل البريد الإلكتروني التالي.

private static void SmtpServer_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            MailMessage thisMesage = (MailMessage) e.UserState;
            if (e.Error != null)
            {
                if (e.Error.InnerException != null)
                {
                    writeMessage("ERROR: Sending Mail: " + thisMesage.Subject + " Msg: "
                                 + e.Error.Message + e.Error.InnerException.Message);
                }

                else
                {
                    writeMessage("ERROR: Sending Mail: " + thisMesage.Subject + " Msg: " + e.Error.Message);
                }
            }
            else
            {
                writeMessage("Success:" + thisMesage.Subject + " sent.");
            }
        if (_messagesPerConnection > 20)
        {  /*Limit # of messages per connection, 
            After send then reset the SmtpClient before next thread release*/
            _smtpServer = new SmtpClient(_mailServer);
            _smtpServer.SendCompleted += SmtpServer_SendCompleted;
            _smtpServer.Port = Convert.ToInt32(_mailPort);
            _smtpServer.UseDefaultCredentials = false;
            _smtpServer.Credentials = new NetworkCredential(_mailUser, _mailPassword);
            _smtpServer.EnableSsl = true;
            _messagesPerConnection = 0;
        }
            _autoResetEvent.Set();//Here is the event reset
            mailWaiting--;
        }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top