LongRunning בביצוע Task חדש?

Sea Bass

New member
LongRunning בביצוע Task חדש?

שלום לכולם,
אני רושם תוכנית קטנה של ביצע טסים בלוף מספר פעמים.
אני יודע שכשאני פותח Task חדש אז לא בהכרח נפתח Task חדש וכיול להיות שטרד אחד מתבצע המספר Tasks וזה נקבע במנגנון פנימי.
הדבר מוביל אותי לשים LongRuning מתי שאני רוצה שה Task יתחיל מיד כי אני רוצה לקבל תוצאה כמה שיותר מהר.
דבר זה מוביל שהטרד נלקח לא מה Threadpoll.
רציתי לדעת איך אתם רושמים את הקוד מתי שאתם רוצים להפעיל מספר Tasks במקביל ולקבל תוצאה מהר ככל הניתן.
האם LongRunning זוהי הדרך הנכונה (למרות שה Task עשוי לעבוד זמן קצר)
הכנתי תכונית לדוגמא:
קוד:
   Task.Factory.StartNew(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    Task.Factory.StartNew((inter) =>
                    {
                        Console.WriteLine("Starting at thread: {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);
                        Console.WriteLine("From pool: {0}", System.Threading.Thread.CurrentThread.IsThreadPoolThread);
                            System.Threading.Thread.Sleep(1000);
                        
                    }, i, TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning);
                }
            }).Wait();
הקוד הזה מתבצע תוך שניה אחת. כמו שצריך ומצופה. אך אם נאי מוריד LongRunning זה יכול לרוץ מספר שניות על אותו טרד.
 

marvin2

New member
מה אתה מנסה לסמלץ ?

בגדול TASK לא אמור לקחת שניה, אלא הרבה פחות (עשרות MS) , ואז האלגוריתם של הטרדפול יהיה יותר יעיל מלפתוח טרדים חדשים מחוץ לטרדפול. יש כאן גם עניין של כמות הטאסקים שאתה רוצה לפתוח, ביחס לכמות הטראדים שיש כרגע בטראדפול. כאשר הטראדפול ריק יחסית , לוקח לו זמן ליצור טראדים חדשים, ואתה תקבל ביצועים שונים כאשר אתה עושה טסט קטן לבין ביצועים במערכת חיה שהטרדפול כבר מלא יחסית בטראדים.
 

Sea Bass

New member
אני לא מנסה לסמלץ, אני מנסה להבין האם יש משהו שאני עושה לא ט

אני פשוט לא מבין למה אני רוצה לעבוד במקביל במצב מאד פשוט, והקוד רץ לי על אותו thread (אני מבין טכנית, אבל לא אוהב את זה)
הנה דוגמא שבו הקוד רץ על threads שונים ועובד כמו שצריך.
קוד:
            var wat = new Stopwatch();
            wat.Start();
            Task.Factory.StartNew(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    Task.Factory.StartNew((inter) =>
                    {
                        Console.WriteLine("Do some work on thread: {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);
                        Thread.Sleep(300);
                    }, i, TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning);
                }
            }).Wait();
            Console.WriteLine(wat.ElapsedMilliseconds);
            Console.ReadKey();
הקוד עכשיו מסיים בזמן (אחרי 300 מילי) בגלל שהוא מושך טרדים חדשים אך לא מה threadPool. זה חיסרון. אך ההיתרון זה שהוא מסיים בזמן.

לעמות זאת אם אני אוריד את זה:
קוד:
var wat = new Stopwatch();
            wat.Start();
            Task.Factory.StartNew(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    Task.Factory.StartNew((inter) =>
                    {
                        Console.WriteLine("Do some work on thread: {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);
                        Thread.Sleep(300);
                    }, i, TaskCreationOptions.AttachedToParent);
                }
            }).Wait();
            Console.WriteLine(wat.ElapsedMilliseconds);
            Console.ReadKey();
הקוד יסיים זה אחרי 2 שניות או שניה וחצי גם.
לכן אני משתמש במקומות ב AttachedToParent ואני לא אוהב את זה.
האם יש דרך אחרת להתשמש ב thread מה pool?
 

marvin2

New member
יש דרכים אחרות

אתה יכול ליצור לך טרדפול משלך, אתה יכול ליצור טרדפול מנגר עם פוליסי משלך ושאז מנגנון הטאקסים יעבוד עליו. אבל עדיין לא הבנתי מה הבעיה. המשימות שלך אכן ארוכות (300 MS) ומנגנון הטרדפוול לא מתאים למשימות מהסוג הזה. בנוסף אתה תראה שאם תריץ את הדוגמא שמשתמשת בטרדפול מספר פעמים באופן רציף, תראה ירידה חדה בזמנים וזאת בגלל כמות הזמן שלוקח להקצות טראדים בתוך הטראד פול (שמגיע עם מספר נמוך מאוד של טראדים)
 
למעלה