PracticU

Managing Resources - חלק 1

בלי כתוביותעם כתוביות
PracticU › קורס תכנות מתקדם - #Advanced .NET C › Managing Resources - חלק 1
מילון מושגים:
רכיב - יחידת בניין עצמאית וניתנת לשימוש חוזר בתוך מערכת או ממשק משתמש, שאחראית על חלק מוגדר מהתפקוד.
זיכרון - רכיב מהיר ונדיף שבו המחשב שומר נתונים ותוכניות בזמן ריצתם. תוכנו נמחק עם כיבוי המחשב.
מחלקה - תבנית בתכנות מונחה עצמים שמגדירה אילו נתונים ופעולות יהיו לאובייקטים שנוצרים ממנה.
בנאי - מתודה מיוחדת שמופעלת אוטומטית בעת יצירת אובייקט ממחלקה, ומאתחלת את ערכיו ההתחלתיים.
חריגה - מצב שגיאה שמתרחש בזמן ריצת התוכנית ומפסיק את המהלך הרגיל, אלא אם הקוד תופס ומטפל בו.
מתודה - פונקציה המוגדרת בתוך מחלקה ומתארת פעולה שאובייקטים מאותה מחלקה יכולים לבצע.
קומפיילר - תוכנה שממירה קוד מקור שנכתב בשפת תכנות לקוד שהמחשב יכול להריץ, ומדווחת על שגיאות תחביר.
תבנית - מבנה בסיסי מוכן שממנו יוצרים פריטים דומים, כמו תבנית עמוד או תבנית מסמך.

Managing Resources - חלק 1
השיעור מתחיל את נושא ניהול המשאבים (Resources). לפני שמטפלים בהם צריך להבין מה נחשב משאב, למה צריך להחזיר אותו למערכת, ואיך מבדילים בין משתנה שמנוהל על ידי ה-Garbage Collector לבין משאב שצריך לסגור בעצמנו.
מהו משאב
1. הגדרה: משאב הוא רכיב פיזי או וירטואלי במחשב, עם זמינות מוגבלת. משתמשים בו לזמן מוגבל ואז מחזירים אותו למערכת כדי שאחרים יוכלו להשתמש בו.
2. דוגמאות: זיכרון, כוח עיבוד, קבצים וחיבורי תקשורת. ערך מחרוזת הוא לא משאב כזה, כי אין מגבלה משמעותית על יצירתו ואין צורך להחזיר אותו.
3. StreamWriter: פתיחת קובץ לכתיבה היא משאב, כי מערכת ההפעלה מונעת מתוכנות אחרות לפתוח את הקובץ בזמן שהוא פתוח אצלנו. לכן צריך לסגור את הקובץ כשמסיימים.
איפה נמצא המשאב
4. Data member: משאב שמוגדר כשדה של מחלקה. הוא חי כל עוד האובייקט חי.
5. משתנה לוקאלי: משאב שנפתח בתוך פונקציה ושייך לה בלבד.
דוגמה: Logger עם קובץ
6. המחלקה: Logger שפותח קובץ טקסט בבנאי ומוסיף אליו הודעה עם תאריך ושעה בכל קריאה ל-Write. הקובץ נפתח במצב הוספה (Append) ולא דורס את הקודם.
7. הבעיה: אחרי הרצה הקובץ ריק. ההודעות נכתבו לחוצץ ולא נשמרו, כי הקובץ לא נסגר.
דיסטרקטור כפתרון שגוי
8. הניסיון: מחליפים את הסגירה בדיסטרקטור של המחלקה. הרעיון שהגארבג' קולקטור יסגור את הקובץ.
9. הבעיות: הדיסטרקטור רץ רק כשהגארבג' קולקטור מחליט לשחרר את האובייקט, ואין לדעת מתי. בהדגמה הקובץ נסגר לפני שהדיסטרקטור הופעל, ולכן הפעולה נכשלה עם חריגה שאומרת שהקובץ סגור. בנוסף אסור לגעת בתוך הדיסטרקטור באובייקטים אחרים שאולי כבר נמחקו.
IDisposable
10. הפתרון: המחלקה מממשת את הממשק IDisposable, שיש בו מתודה אחת בשם Dispose. בתוך Dispose סוגרים את המשאב.
11. אחריות המשתמש: מי שמשתמש במחלקה צריך לקרוא ל-Dispose כשמסיים. הקומפיילר לא דורש זאת, ולכן זו אחריות של השימוש.
12. Close ו-Dispose: ב-StreamWriter הפונקציה Close קוראת ל-Dispose. בשני המקרים הקובץ נסגר.
Using
13. הצורך: אם העבודה עם המשאב נכשלת באמצע, קריאה ישירה ל-Dispose לא תתבצע. לכן משתמשים בחלק מבלוק try-finally.
14. בלוק using: מקבל אובייקט שמממש IDisposable. בתוך הבלוק מבצעים את העבודה, ובסופו נקראת Dispose, גם אם הייתה חריגה. בהדגמה הקובץ נכתב ונסגר נכון גם כשהייתה חריגה באמצע.
15. מסקנה: משאב שמשמש כדאטה ממבר צריך מימוש של IDisposable. משאב לוקאלי נסגר בבלוק using.
בשיעור הבא נראה את התבנית המלאה של Dispose, שמטפלת גם במשאבים מנוהלים וגם בלא מנוהלים.
השיעור הבא בקורס: Managing Resources - חלק 2

פרקי ההרצאה: Managing Resources - חלק 1

  1. 00:00

    מהו Resource ומשאב מוגבל

  2. 01:55

    פתיחת קובץ עם StreamWriter

  3. 03:53

    Resource כ-Data Member או משתנה לוקאלי

  4. 05:53

    בניית מחלקת Logger לכתיבה לקובץ

  5. 10:03

    כתיבה ל-Log עם LOGGER.Write

  6. 11:55

    ההבדל בין Resource לזיכרון של ה-GC

  7. 13:13

    דוגמאות למשאבים - קבצים, DATABASE, Request

תמלול ההרצאה: Managing Resources - חלק 1

הטקסט המלא של הדקות הראשונות בהרצאה «Managing Resources - חלק 1» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.

  1. 00:03

    אחרי שראינו מה זה garbage collector וראינו שהgarbage collector הוא זה שאחראי על הקצאת מקום בזיכרון וגם על שחרור המקום בזיכרון אנחנו עוברים לנושא שנקרא managing resources קודם כל בואו ניתן הגדרה ל-resource resource בעברית משאב זה בעצם כל רכיב פיזי או וירטואלי בתוך המחשב שיש לו זמינות מוגבלת זאת אומרת

  2. 00:35

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

  3. 00:51

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

  4. 01:03

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

  5. 01:18

    אם לדוגמה אנחנו רוצים להשתמש באיזושהי סטרינג, אז כל מה שאני עושה, אני יוצר לעצמי איזושהי מחרוזת, אני יכול להשתמש איתה, להכניס לתוך הערך, להציג אותה.

  6. 01:34

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

  7. 01:57

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

  8. 02:08

    אנחנו פותחים אובייקט שנקרא StreamWriter. סטרים רייטר אנחנו יודעים שזה בעצם מאפשר לנו לכתוב לקבצי טקסט. ניקח פה רייטר ונפתח פה איזשהו קובץ c.2 myfile.txt writer.write ומה שעשינו עכשיו ופתחנו קובץ לצורך כתיבה.

  9. 02:44

    זה כן נחשב ריסורס. למה? מפני שמי שנתנו את הזכות להשתמש עם הקובץ זאת מערכת ההפעלה וברגע שהיא אמרה לנו אין בעיה אני מאפשרת לכם ליצור פה איזשהו קובץ ולהשתמש איתו אז היא דואגת לזה שאף תוכנה אחרת כולל אנחנו לא נוכל לפתוח את הקובץ הזה בזמן שהוא פתוח על ידינו זה אומר שאנחנו צריכים

  10. 03:11

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

  11. 03:40

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

  12. 03:53

    עכשיו אם אני מסתכל על מה זה באמת זה סך הכל איזשהו משתנה אובייקט מסוים שאני פותח אותו משתמש בו ובסיום השימוש אני רוצה לסגור אותו. אז אם אני מסתפק עם אובייקטים יש לי רק שני מקומות שבהם אני יכול להגדיר אובייקטים או שאני מגדיר אובייקט כdata member של איזושהי מחלקה יש לנו פה איזושהי מחלקה a ואנחנו מגדירים אובייקט מבחינתנו resource כרגע.

  13. 04:27

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

  14. 04:56

    למה אני מראה את שתי השיטות האלה או שני המקרים השונים האלה? מפני שהטיפול בריסורס הוא שונה עבור כל אחד מהם. אין לנו יותר מקומות שבהם אנחנו יכולים להגדיר משתנה בתכנות, לפחות ב-C-Sharp, או שאתה Data Member של מחלקה, או שאתה משתנה בתוך פונקציה.

  15. 05:15

    בשפות אחרות היו עוד כל מיני מקומות, לדוגמה, יכלתם לפתוח איזשהו משתנה באזור נקי לגמרי שנקרא מודול בשפה של Visual Basic לדוגמה. אבל אין לנו את הדברים האלה כרגע ב-C-Sharp, ולכן אנחנו מתעסקים רק עם או Data Member או משתנה לוקאלי בתוך פונקציה.

  16. 05:38

    וכאמור הטיפול בכל אחד מהם הוא שונה. אז בואו נסתכל איך אנחנו באמת מטפלים בשני המקרים האלה. אז מה שנעשה זה ניקח קודם כל את הטיפול במצב שהריסורס שבו אנחנו משתמשים איתו הוא data member של מחלקה.

  17. 05:56

    בואו ניקח stream writer ונבנה מחלקה שנקראת logger. logger זאת מחלקה שבדרך כלל אתם תרצו לבנות, שמאפשרת לכם לכתוב כל מיני דברים לקובץ טקסטואלי במהלך התוכנית בשביל לעקוב אחרי כל מיני דברים שקרו בתוכנית, בעיקר לצורכי דיבאגינג, לדעת מה המשתמש עשה במהלך פעילות התוכנית.

  18. 06:22

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

  19. 06:35

    אבל כמובן אנחנו רוצים בסיום העבודה עם הלוגר לאפשר לסגור את ה-resource. אחד הדברים החשובים שצריך לבכור בנוגע לעבודה עם resources זה סיימנו לעבוד איתו אנחנו חייבים לסגור אותו אם אנחנו לא נסגור אותו יהיה לנו משהו לא בסדר עם התוכנית או לוגית אף אחד לא יוכל לעבוד עם אותו קובץ

  20. 06:57

    או אותו resource או שפתאום הוא זולל לנו המון המון זיכרון ולא שחררנו או שהוא זולל לנו המון מאבד ולא שחררנו אותו אנחנו צריכים להיפטר מ-resources ברגע שאנחנו לא רוצים להשתמש בהם יותר.

  21. 07:14

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

  22. 07:36

    בגלל שזה משתנה פרייבט נתחיל איתו עם underline. זה אומר שאם מישהו יוצר אובייקט מהמחלקה לוגר, אוטומטית אנחנו מצביעים על הקובץ הזה שאפילו כדאי לשלוח פה true עבור pending.

  23. 07:56

    אנחנו רואים שאנחנו לא רוצים לדרוס את הלוג הקודם שנרשם, אנחנו רוצים להוסיף אליו, ואנחנו רוצים לאפשר איזושהי פונקציה שתכתוב מידע לקובץ. יש לנו פה public, יש לנו void right ואנחנו יכולים לקבל איזושהי סטרינג, מסג', אנחנו רוצים לכתוב אותה לתוך האובייקט writer עם התאריך והשעה הנוכחיים, כדי שנדע מה המשתמש בדיוק עשה,

  24. 08:40

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

  25. 09:10

    עכשיו בוא נניח שיש לנו פה איזושהי פונקציה do work הפונקציה הזאת עושה איזושהי עבודה ואנחנו רוצים במהלך הפונקציה לכתוב ללוג. אוקיי, אז בואו נפתח את הלוגר. ברגע שעשינו את השורת קוד הזאת, זה אומר שיצרנו אובייקט מהלוגר, וכעת נוצר לנו האובייקט הזה מיידית שמצביע על הקובץ logger.log בכונן ה-C.

  26. 09:56

    הוא כמובן נפתח במצב של אפנדינג, ואנחנו יכולים להוסיף ללוג הקודם. בסדר, אז מה אנחנו צריכים לעשות כרגע? אנחנו צריכים להתחיל לכתוב לוגר נקודה right, בואו נכתוב שבשעה הזאת בדיוק אנחנו מבצעים starting do work, שנדע שהמשתמש עשה איזה משהו, הפונקציה הזאת התחילה.

  27. 10:23

    בואו נכתוב כאן ending do work, אין בעיה, בסדר גמור. אוקיי, עכשיו אם אני קורא לדו וורק, מבצע פה console read line בתוכנית, מבצע קומפילציה, נריץ, אנחנו רואים ש-DoWork ביצעה את מה שהיא ביצעה, ובואו ניכנס לקונן C, נחפש את הקובץ הזה.

  28. 11:12

    יש לנו פה את קונן C, הנה הקובץ, logger.log, נפתח אותו, הוא ריק לגמרי. מה, לא כתבתי לתוכו? בהחלט כתבנו, אבל לא סגרנו אותו.

  29. 11:27

    זוכרים? אמרנו, במידה ואנחנו מסיימים להשתמש עם איזשהו ריסורס, חשוב לסגור אותו.

  30. 11:38

    עכשיו, כשהתוכנית הסתיימה, אז במקרים מסוימים היא סוגרת אוטומטית resources. את זה אפילו היא לא סגרה, שימו לב שאפילו התוכנית הסתיימה ולא כתבנו שום דבר לקובץ.

  31. 11:53

    למה לא כתבנו שום דבר לקובץ? כי לא סגרנו את ה-resources. אז כל מה שאנחנו מראים כרגע זה שאם אנחנו משתמשים במשהו שנחשב resource, אנחנו צריכים לסגור אותו בפיום השימוש בו.

  32. 12:07

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

  33. 12:32

    זה היה נכון בשפת C ובשפת C++ ובכל כל מיני שפות ישנות שאין להן garbage collector. בדוטנט קיים garbage collector שדואג במקומנו לשחרור הזיכרון של האובייקטים reference types שהוא מייצר.

  34. 12:49

    לכן אנחנו לא צריכים לבגור שום דבר שקשור לזיכרון. כאשר אני מדבר על resources שאנחנו צריכים לסגור אותם בסיום השימוש בהם, אני לא מדבר על שחרור אובייקטים שהgarbage collector מבצע.

  35. 13:04

    אני מדבר על כל מיני אובייקטים שאנחנו משתמשים איתם בתוכנית, שנחשבים resource מבחינת מערכת ההפעלה ומבחינת גורמים אחרים במחשב, ואנחנו חייבים לסגור אותם בכדי להחזיר אותם למערכת.

  36. 13:21

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

  37. 13:35

    ריקווסט לאיזשהו אתר, אתם יוצרים איזשהו ריקווסט בשביל לגלוש לאיזשהו אתר, עליכם לסגור את הריקווסט בכדי לשחרר את האתר אינטרנט או לשחרר את התקשורת לאתר, או ליתר דיוק ריספונס, קיבלתם תשובה מאיזשהו אתר,

  38. 13:54

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

לקורס המלא: קורס תכנות מתקדם ב‑#C ודוט-נט

ההרצאה הקודמת: תרגילים על Garbage Collector

ההרצאה הבאה: Managing Resources - חלק 2

הרצאות קשורות מקורסים אחרים

  • הרצאה על Resources
  • Qualifying Resources
  • הסבר על GROUPS RESOURCES

קורסים נוספים במסלול

  • קורס WinForms - תוכנות רגילות בווינדוס
  • פרויקט מעשי ב-#C - בונים מחשבון פשוט
  • פרויקט מעשי ב-#C - ספר טלפונים
  • פרויקט מעשי ב-#C - תוכנת צייר
  • קורס ADO.NET - חיבור אתר למסד נתונים
  • קורס WCF - תקשורת למתקדמים בדוט-נט