إرسال رسائل بريد إلكتروني جماعية في الخلفية - إنشاء مؤشر ترابط أو استخدم ThreadPool؟
-
30-09-2019 - |
سؤال
لديّ تطبيق يؤدي فيه الإجراء إلى عدد من رسائل البريد الإلكتروني التي سيتم إرسالها. عدد رسائل البريد الإلكتروني متغيرة ويمكن أن يكون في أي مكان من 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
لذا فإن اقتراحي هو استخدام 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
}