שני הסנטים שלי על השיטות Thread.Abort ו- Thread. Interrupt

ב- C #, ייתכן שתצטרך לשחרר שרשור שנחסם. כדי להשיג זאת, ישנן שתי שיטות בהן תוכלו לנצל. אלה כוללים את השיטות Thread.Abort ו- Thread.Intrrupt.

מה עושה שיטת Thread.Abort?

כדי לסיים שרשור אתה יכול לנצל את שיטת ההפלה של מחזור החוט. שים לב שכדי להתחיל את תהליך סיום השרשור, שיטת ההפלה של מחלקת השחלה בעת הפעלתה, מעלה ThreadAbortException בשרשור עליו נקרא. יש לציין כי באפשרותך לנצל את שיטת Abort של מחזור Thread כדי לסיים אפילו שרשור שאינו חסום. אם החוט שנקטע נמצא במצב המתנה, הוא מעיר אותו ואז גורם לזריקת ThreadInterruptedException. באופן דומה, אם אתה קורא לשיטת Thread.Abort על חוט שנמצא במצב המתנה, זמן הריצה מעיר את השרשור ואז זורק ThreadAbortException.

אתה יכול לתפוס את ThreadAbortException בבלוק התפס. עם זאת, אם לא תקרא לשיטת ResetAbort, חריג זה יושלך מחדש בסוף חסימת התפס. הקריאה לשיטת ResetAbort תמנע מהזרקת ה- ThreadAbortException בסוף גוש התפיסה. בניגוד לאופן שבו פועלת שיטות Thread.Inturrupt, אם החוט שעליו נקראת שיטת Thread.Abort אינו חסום, שיטת Thread.Abort זורקת ThreadAbortException על החוט.

ברוב המקרים (אלא אם כן ברצונך לסגור את תחום היישום לאחר הפסקת השרשור), אינך צריך להשתמש בשיטה זו כלל. שים לב ששיטת Response.Redirect ב- ASP.Net זורקת ThreadAbortException.

מה המטרה של שיטת Thread.Interrupt?

באפשרותך להשתמש בשיטת Thread.Interrupt כדי להפריע לשרשור שנמצא במצב WaitSleepJoin. עם זאת, אף אחת מהגישות הללו (Thread.Abort או Thread.Intrrupt שיחות שיטה) איננה בטוחה בחוט. בעוד ששיטת Thread.Abort זורקת ThreadAbortException, שיטת Thread.Interrupt זורקת ThreadInterruptException. בעיקרו של דבר, קריאה לשיטת Thread.Interrupt קוטעת את החוט ומשליכה ThreadInterruptedException כדי להפריע לשרשור בתוך שיחה חוסמת. עליך להתמודד עם חריג זה בקוד שלך שלא מצליח, וזמן הריצה יפסיק את השרשור עליו נקראה שיטת Thread.Interrupt. יש לציין כי קריאה ל Thread.Interrupt אינה מפריעה לשרשור שמבצע קוד לא מנוהל.

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

static void Main(string[] args)

       {

           Thread thread = new Thread(ThreadMethod);

           thread.Start();

           thread.Interrupt();

           Console.Read();

       }

       private static void ThreadMethod()

       {

           try

           {

               Thread.Sleep(Timeout.Infinite);

           }

           catch (ThreadInterruptedException)

           {

             Console.Write("ThreadInterruptedException has been called forcibly.");

           }

       }

כאשר התוכנית לעיל מופעלת, ההודעה "ThreadInterruptedException נקראה בכוח" תוצג במסוף.

מה קורה אם החוט המופרע אינו חסום? אני אתה מתקשר לשרשור. הפסק על שרשור שאינו חסום, השרשור ימשיך להתבצע עד למועד חסימתו הבא. ברוב המקרים, אתה בכלל לא צריך להשתמש ב- Thread. Interrupt. אתה יכול להשיג את אותו הדבר באמצעות מבני איתות או אסימונים לביטול.

האם עלי להשתמש בשיטת Thread.Abort או בשיטת Thread.Interrupt?

אז מתי עלי להשתמש בשיטות Thread.Abort לעומת Thread.Intrrupt בתוכנית שלי? אם עלי לבטל פעולה מסוימת, באיזו מהשיטות הללו עלי להשתמש? התשובה הכנה שלי היא שלעולם אל תשתמש באף אחת מהשיטות הללו כדי לסיים פתיל. רצוי לא להשתמש ב- Thread.Abort או Thread. שיטות הפסקה לסיום שרשור - כדאי להיעזר באובייטי סינכרון (כמו WaitHandles או Semaphores) ולבצע סיום חינני של החוטים שבהם אתה משתמש. קטע הקוד הבא ממחיש כיצד תוכלו לנצל את WaitHandle כדי לאפשר לשרשור להפסיק בחן.

private void ThreadMethod()

{

   while(!manualResetEventObject.WaitOne(TimeSpan.FromMilliseconds(100)))

   {

       //Write your code here

   }

}

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