ج# أفضل الممارسات الموثوقة للتنفيذ المؤجل/المجدول

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

سؤال

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

أفكر في السير في هذا الطريق:

يمكن أن يكون لدي جدول في قاعدة البيانات (أو حتى قائمة انتظار الرسائل) يسمى TaskTable والذي يمكن أن يحتوي على TaskID(PK) وTaskName(varchar) وTaskStatus(enum Success,failed, مجدولة) وTimeOfExecution.لكنني بحاجة إلى خدمة Windows التي تقوم بشكل دوري باستقصاء قاعدة البيانات عن أي مهام غير منفذة.المشكلة التي أواجهها هي أن:ما الذي أستخدمه كاسم المهمة لحفظه في قاعدة البيانات؟اسم الصف؟اسم الفئة والطريقة ToString؟وكيف يمكنني تحويل السلسلة مرة أخرى واستدعاء استدعاءات الطريقة برمجيًا (لا أريد الحصول على بيان تبديل عملاق)؟ستبدو المهمة النموذجية أدناه.لذلك كنت بحاجة إلى أن أتمكن من الحصول على اسم المهمة "SendIncompleteNotification" واسم الفئة وحفظها في قاعدة البيانات واستدعاءها برمجيًا عند استرجاعها

public static Task<string> SendIncompleteNotification
{
  get
    {
      return new Task<string>
        (
          a => Console.WriteLine("Sample Task")
          , "This is a sample task which does nothing."
        );
   }
}

المشكلة الآن هي أنني أواجه مشكلة في حفظ اسم الطريقة/الخاصية برمجيًا.

var type = ApplicationTask.SendIncompleteNotification.GetType();
//type.Name shows "Task`1" rather than SendIncompleteNotification

هل هناك طرق أفضل للتعامل مع هذا الوضع؟شكرًا!

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

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

المحلول

هل قاعدة البيانات متطلب؟

إذا لم يكن الأمر كذلك، فماذا عن مهمة Windows المجدولة (لديهم ميل إلى "العمل فقط") والتي تستدعي تطبيق وحدة تحكم عام.يمكن أن تكون الوسائط الخاصة بتطبيق وحدة التحكم هي:

  • ملف DLL يحتوي على المهمة المطلوب تنفيذها
  • اسم الفئة التي تنفذ الواجهة التي تحددها
  • حجج أخرى

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

يحرر:مثال:

interface ITask
{
    void Execute(ExcecutionContext context);
}

[TaskName("Send Emails")
class SendEmailsTask : ITask
{
    public void Execute(ExcecutionContext context) 
    {
        // Send emails. ExecutionContext might contain a dictionary of 
        // key/value pairs for additional arguments needed for your task. 
    }
}

class TaskExecuter 
{
    public void ExecuteTask(string name) 
    {
        // "name" comes from the database entry
        var types = Assembly.GetExecutingAssembly().GetTypes();    
        foreach (var type in types)
        {
            // Check type.GetCustomAttributes for the TaskAttribute, then check the name
        }
    }
}

تحرير 2:هذا ردًا على نموذج التعليمات البرمجية الخاص بك.

class YourClass
{
    public static Task<string> SendIncompleteNotification
    {
        get {
            return new Task<string>(
                s => Console.WriteLine("Executing task... arguments: {0}", s),
                "My task");
        }
    }
}


interface ITask
{
    void Execute(object o);
}

class Task<T> : ITask
{        
    public Task(Action<T> action, string name)
    {
        Action = action;
    }

    public string Name { get; set; }
    public Action<T> Action { get; set; }

    void ITask.Execute(object o)
    {
        Action((T)o);
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Assume that this is what is stored in the database
        var typeName = typeof (YourClass).FullName;
        var propertyName = "SendIncompleteNotification";
        var arguments = "some arguments";

        // Execute the task
        var type = Type.GetType(typeName);
        var property = type.GetProperty(propertyName);
        var task = (ITask)property.GetValue(null, null);
        task.Execute(arguments);
        Console.ReadKey();
    }
}

نصائح أخرى

وقد ترغب في النظر في ويندوز سير العمل. وهي مصممة لعمليات تشغيل الطويل، يمكن استمرت إلى قاعدة بيانات واستيقظ على الحدث أو مؤقت، بقدر ما أعرف.

وتخزين FULLNAME التجمع، واكتب الاسم بالكامل واسم الأسلوب. وإذا افترضنا أن توقيع الأسلوب هو شيء يمكن التنبؤ به (مثل أية معلمات والعودة الفراغ)

1) إنشاء مثيل من التجمع باستخدام أسلوب LoadFrom ثابت من النوع الجمعية.

2) الحصول على مرجع إلى نوع فئة من التجميع الخاص بك باستخدام أسلوب GetType

و3) للحصول على سبيل المثال MethodInfo من نوع باستخدام طريقة GetMethod

و4) إنشاء مثيل من النوع باستخدام Activator.CreateInstance

و5) تنفيذ أسلوب باستخدام استدعاء مثيل MethodInfo، ويمر في مثيل فئة من الخطوة 4. (آسف أنني في جهاز كمبيوتر عام دون نسخة من VS لكرنك خارج رمز حقيقي ولكن تلك الخطوات من 5 القيام به.

وأيضا إذا كنت تستخدم SQL 2005 النظر في استخدام كائن SqlDependency والحصول على "أخطر" عندما تتغير talbe الخاص بك بدلا من الاقتراع.

هل نظرت إلى الكوارتز ، وأنها تعمل بشكل جيد، وأنا متأكد من أنها تنفذ جميع الميزات التي تحتاج إليها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top