כיצד לבנות מתזמן משימות משלך ב- C #

TPL (Task Parallel Library) היא אחת התכונות החדשות המעניינות בגרסאות האחרונות של .NET Framework, לאחר שהוצגה לראשונה ב- .NET Framework 4.0. כדי לעבוד עם ה- TPL יהיה עליכם לנצל את מרחב השמות System.Threading.Tasks.

מהם מתזמני משימות? מדוע אנו זקוקים להם?

עכשיו, איך המשימות מתוזמנות? ובכן, יש רכיב שנקרא מתזמן משימות שאחראי לתזמון המשימות שלך. למעשה, זוהי הפשטה של ​​אובייקט ברמה נמוכה שיכול לתור את המשימות שלך לשרשורים.

.NET Framework מספק לך שני מתזמני משימות. אלה כוללים את מתזמן המשימות המוגדר כברירת מחדל הפועל במאגר החוטים של .NET, ומתזמן משימות אחר שמבצע בהקשר הסינכרון של יעד מוגדר. שים לב שמתזמן המשימות המוגדר כברירת מחדל של ה- TPL מנצל את מאגר החוטים של .NET Framework. מאגר החוטים מיוצג בתורו על ידי מחלקת ThreadPool הכלולה במרחב השמות System.Threading.Tasks.

למרות שמתזמן המשימות המוגדר כברירת מחדל יספיק לרוב, ייתכן שתרצה לבנות מתזמן משימות מותאם אישית משלך כדי לספק פונקציות נוספות, כלומר תכונות שאינן מסופקות על ידי מתזמן המשימות המוגדר כברירת מחדל. תכונות כאלה עשויות לכלול, ביצוע FIFO, מידת המקביל וכו '.

הרחב את הכיתה TaskScheduler ב- C #

כדי לבנות מתזמן משימות מותאם אישית משלך יהיה עליך ליצור מחלקה שמרחיבה את המחלקה System.Threading.Tasks.TaskScheduler. לכן, כדי לבנות מתזמן משימות מותאם אישית, יהיה עליך להרחיב את המחלקה המופשטת TaskScheduler ולעקוף את השיטות הבאות.

  • QueueTask מחזיר בטל ומקבל אובייקט Task כפרמטר ושיטה זו נקראת כאשר מתוזמנת משימה
  • GetScheduledTasks מחזירה רשימה (IE המספיקה לדיוק) של כל המשימות שתוזמנו
  • TryExecuteTaskInline משמש לביצוע משימות מוטבעות, כלומר בשרשור הנוכחי. במקרה זה, המשימות מבוצעות ללא צורך בתור להן

קטע הקוד הבא מראה כיצד ניתן להרחיב את מחלקת TaskScheduler כדי ליישם את מתזמן ההתאמה האישית שלך ב- C #.

מחלקה ציבורית CustomTaskScheduler: TaskScheduler, IDisposable

    {

    }

כפי שדנו קודם במאמר זה, יהיה עליך לבטל את השיטות GetScheduledTasks, QueueTask ו- TryExecuteTaskInline בתזמון המשימות המותאם אישית.

מחלקה אטומה ציבורית CustomTaskScheduler: TaskScheduler, IDisposable

  {

        עקיפה מוגנת IEnumerable GetScheduledTasks ()

        {

            //לעשות

        }

        עקיפה מוגנת void QueueTask (משימת משימה)

        {

             //לעשות

        }

        עקיפה מוגנת של bool TryExecuteTaskInline (משימת משימה, משימת boolWasPreviouslyQueued)

        {

            //לעשות

        }

        חלל ציבורי הרחק ()

        {

            //לעשות

        }

  }

השתמש ב- BlockingCollection לאחסון אוסף של אובייקטים משימה ב- C #

נתחיל כעת ליישם את מתזמן המשימות המותאם אישית שלנו. קטע הקוד הבא מראה כיצד ניתן למנף את BlockingCollection לאחסון אוסף של אובייקטים למשימה.

מחלקה אטומה ציבורית CustomTaskScheduler: TaskScheduler, IDisposable

 {

        משימות פרטיות של BlockingCollectionCollection = BlockingCollection חדש ();

        פרטי לקריאה בלבד אשכול mainThread = null;

        CustomTaskScheduler ציבורי ()

        {

            mainThread = שרשור חדש (ThreadStart חדש (ביצוע));

            אם (! mainThread.IsAlive)

            {

                mainThread.Start ();

            }

        }

        חלל פרטי ביצוע ()

        {

            foreach (var task in taskCollection.GetConsumingEnumerable ())

            {

                TryExecuteTask (משימה);

            }

        } 

      // שיטות אחרות

  }

עיין בבנאי המחלקה CustomTaskScheduler. שים לב כיצד נוצר שרשור חדש והתחיל להריץ את שיטת הביצוע.

יישם את השיטות GetScheduledTasks, QueueTask ו- TryExecuteTaskInline ב- C #

לאחר מכן, עלינו ליישם את שלוש השיטות שעלינו לעקוף בתזמון המשימות המותאם אישית שלנו. שלוש השיטות הללו כוללות את GetScheduledTasks, QueueTask ו- TryExecuteTaskInline.

השיטה GetScheduledTasks מחזירה את המופע של אוסף המשימות כ- IEnumerable. זה משמש כדי שתוכל למנות את האוסף כפי שמוצג בשיטת הביצוע. שיטת QueueTask מקבלת אובייקט Task כפרמטר ושומרת אותו באוסף המשימות. לשיטת TryExecuteTaskInline אין מימוש - אני אשאיר לקורא ליישם אותה.

עקיפה מוגנת IEnumerable GetScheduledTasks ()

        {

            החזר משימות Collection.ToArray ();

        }

        עקיפה מוגנת void QueueTask (משימת משימה)

        {

            אם (משימה! = null)

                taskCollection.Add (משימה);

        }

        עקיפה מוגנת של bool TryExecuteTaskInline (משימת משימה, משימת boolWasPreviouslyQueued)

        {

            להחזיר כוזב;

        }

השלם דוגמה של CustomTaskScheduler ב- C #

רישום הקוד הבא ממחיש את הגרסה הסופית של CustomTaskScheduler שלנו.

מחלקה אטומה ציבורית CustomTaskScheduler: TaskScheduler, IDisposable

    {

        משימות פרטיות של BlockingCollectionCollection = BlockingCollection חדש ();

        פרטי לקריאה בלבד אשכול mainThread = null;

        CustomTaskScheduler ציבורי ()

        {

            mainThread = שרשור חדש (ThreadStart חדש (ביצוע));

            אם (! mainThread.IsAlive)

            {

                mainThread.Start ();

            }

        }

        חלל פרטי ביצוע ()

        {

            foreach (var task in taskCollection.GetConsumingEnumerable ())

            {

                TryExecuteTask (משימה);

            }

        }

        עקיפה מוגנת IEnumerable GetScheduledTasks ()

        {

            החזר משימות Collection.ToArray ();

        }

        עקיפה מוגנת void QueueTask (משימת משימה)

        {

            אם (משימה! = null)

                taskCollection.Add (משימה);           

        }

        עקיפה מוגנת של bool TryExecuteTaskInline (משימת משימה, משימת boolWasPreviouslyQueued)

        {

            להחזיר כוזב;

        }

        חלל פרטי להשליך (סילוק בול)

        {

            אם (! סילוק) תשוב;

            taskCollection.CompleteAdding ();

            משימות Collection.Dispose ();

        }

        חלל ציבורי הרחק ()

        {

            להשליך (נכון);

            GC.SuppressFinalize (זה);

        }

    }

כדי להשתמש בתזמון המשימות המותאם אישית שיישמנו זה עתה, אתה יכול להשתמש בקטע הקוד הבא:

CustomTaskScheduler taskScheduler = CustomTaskScheduler חדש ();

Task.Factory.StartNew (() => SomeMethod (), CancellationToken.None, TaskCreationOptions.None, taskScheduler);

כיצד לעשות יותר ב- C #:

  • מתי להשתמש בכיתה מופשטת לעומת ממשק ב- C #
  • כיצד לעבוד עם AutoMapper ב- C #
  • כיצד להשתמש בביטויי למבדה ב- C #
  • כיצד לעבוד עם נציגי Action, Func ו- Predicate ב- C #
  • כיצד לעבוד עם נציגים ב- C #
  • כיצד ליישם לוגר פשוט ב- C #
  • כיצד לעבוד עם תכונות ב- C #
  • כיצד לעבוד עם log4net ב- C #
  • כיצד ליישם את דפוס עיצוב המאגר ב- C #
  • כיצד לעבוד עם השתקפות ב- C #
  • כיצד לעבוד עם מערכת קבצים ב- C #
  • כיצד לבצע אתחול עצל ב- C #
  • כיצד לעבוד עם MSM ב- C #
  • כיצד לעבוד עם שיטות הרחבה ב- C #
  • איך לנו ביטויים למבדה ב- C #
  • מתי להשתמש במילת המפתח ההפכפכה ב- C #
  • כיצד להשתמש במילת המפתח תשואה ב- C #
  • כיצד ליישם פולימורפיזם ב- C #
  • כיצד לבנות מתזמן משימות משלך ב- C #
  • כיצד לעבוד עם RabbitM ב- C #
  • איך לעבוד עם ציצית ב C #
  • חקר שיטות וירטואליות ומופשטות ב- C #