إرسال رسائل بريد إلكتروني جماعية في الخلفية - إنشاء مؤشر ترابط أو استخدم ThreadPool؟

StackOverflow https://stackoverflow.com/questions/4138405

سؤال

لديّ تطبيق يؤدي فيه الإجراء إلى عدد من رسائل البريد الإلكتروني التي سيتم إرسالها. عدد رسائل البريد الإلكتروني متغيرة ويمكن أن يكون في أي مكان من 10 إلى 1000 لكل عمل.

لا أريد التطبيق يشنق بينما يتم إرسال رسائل البريد الإلكتروني (مما يزعج المستخدم) ويرغب في إرسالها في الخلفية.

لم أستخدم المواضيع في الماضي ، ولهذا السبب أحتاج إلى مساعدتك. هل يمكنك إنشاء مواضيع يدويًا أم أن هذه حالة جيدة لاستخدام ThreadPool؟ أريد أن تكون هذه المهمة ذات أولوية منخفضة وأن تستخدم أقل قدر ممكن من الموارد لأنني لا أمانع حتى لو تأخرت البريد الإلكتروني ساعة واحدة.

نقدر مساعدتكم
ماركو

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

المحلول

هنا يذهب اقتراحًا آخر ... إذا كنت تستخدم DB ، فقم بإنشاء مهمة (أي إنشاء جدول يمثل مهمة يتعين القيام بها) تتعلق بالرسائل التي تحتاج إلى إرسالها واستخدامها Quartz.net أو ما شابه (يمكنك إنشاء خدمة Windows أيضًا) تبحث عن مهام غير مكتملة وتنفذها (وضع علامة عليها كما تم في حالة تنفيذها بنجاح).

نصائح أخرى

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

الخيار الأفضل لك هو إنشاء خدمة خارجية (إما خدمة WCF تعمل في IIS ، أو خدمة Windows التي تحتوي على واجهة WCF مكشوفة) والتي يمكن أن تتصل صفحة .NET بشكل غير متزامن ، وتشغيل هذا الطلب حتى يكمل. لا تقلق بشأن الترابط وما إلى ذلك. إنه يعمل في عملية خاصة به وعندما يتم ذلك يكمله. نظرًا لأنك لا تهتم بإخبار المستخدم الذي تم إنجازه ، فلن تقلق بشأن التواصل مرة أخرى. وبهذه الطريقة ، إذا كنت بحاجة إلى الحصول على بعض الصفحات الأخرى ، فاستخدم واجهة الخدمة نفسها ، فسيتم استدعاؤها.

صفحات في البدء مع WCF:

http://bloggingabout.net/blogs/dennis/archive/2007/04/20/wcf-simple-example.aspx

http://msdn.microsoft.com/en-us/library/bb332338.aspx

http://www.c-sharpcorner.com/articles/articlelisting.aspx؟sectionID=1&SubSectionID=192

كيف تبدأ في استخدام WCF/WPF؟

لذا فإن اقتراحي هو استخدام Threadpool. سيسمح لك ذلك بتصوير كل شيء بدلاً من ذلك لتشغيل كل واحد منها بشكل منفصل ، مما يجعله يستخدم موارد أقل ، ولكن بالطبع ، أخذ وقتًا أطول لمعالجة كل شيء ، ولكن كما قلت ، فإن الوقت ليس مشكلة.

يمكنك ببساطة استخدام عمال الخلفية صف دراسي.

تحتوي صفحة MSDN المرتبطة على مثال رائع مع التقارير المرحلية وإمكانية إلغاء العملية.

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

EDIT2:
إذا كنت ترغب في إرسال العديد من الرسائل بالتوازي ، يمكنك البحث المكتبة الموازية للمهمة.

يمكنك استخدام المهام لتفرخ موضوع العامل لمعالجة رسائل البريد الإلكتروني.

إذا كان هذا يطرق وحدة المعالجة المركزية أكثر من اللازم ، فيمكنك إنشاء جدولة جديدة تقلل من التزامن: http://msdn.microsoft.com/en-us/library/ee789351.aspx

static void StartMailTasks(string[] addresses)
{
    List<Task> tasks = new List<Task>();
    foreach (var address in addresses)
    {
        tasks.Add(Task.Factory.StartNew(Email, address));
    }

    Task.Factory.ContinueWhenAll(tasks.ToArray(), AllDone, TaskContinuationOptions.OnlyOnRanToCompletion);
    Task.Factory.ContinueWhenAny(tasks.ToArray(), ReportError, TaskContinuationOptions.OnlyOnFaulted);
}

static void AllDone(Task[] tasks)
{
    // All is well
}

static void ReportError(Task errorTask)
{
    // Log or report the error
}

static void Email(object state )
{
    // send the e-mail  
    // Can throw error, if needed
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top