PracticU

AppDomains

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

AppDomains
השיעור עוסק ב-AppDomain, מעטפת פנימית בתוך התהליך (Process) שמשמשת להרצת אסמבליז. נראה למה משתמשים בה, איך מריצים בתוכה קובץ הרצה ו-DLL, ואיך מעבירים מידע בין מעטפות.
מה זה AppDomain
1. תהליך ומעטפת: מערכת ההפעלה יוצרת תהליך לכל קובץ הרצה. בתוך התהליך .NET יוצר AppDomain ראשי, וכל האסמבליז נטענים אליו.
2. מעטפות נוספות: אפשר לפתוח AppDomain נוסף בתוך אותו תהליך. לכל אחד יש אזור זיכרון גלובלי ומשתנים סטטיים משלו, והאסמבליז שנטענו בו נפרדים מאלה שבאחרים.
3. הריסה: כשמסיימים עם AppDomain מורידים אותו בבת אחת, וכל הזיכרון והאסמבליז שלו משתחררים.
למה משתמשים בו
4. ספרייה של צד שלישי: רכיב שרוצים להפריד מהזיכרון של האפליקציה נטען לתוך AppDomain נפרד, ולאחר השימוש הוא מוסר יחד עם כל משאביו.
5. הפרדה לוגית: שרת שמעדכן מידע יכול לטעון את המידע החדש ב-AppDomain חדש. לקוחות חדשים עוברים אליו, ואחרי שהישנים מתנתקים הישן נהרס.
הרצת קובץ הרצה בתוך AppDomain
6. הדוגמה: מחשבון שמקבל שלושה ארגומנטים, מספר, אופרטור ומספר, ומחזיר תוצאה כ-int.
7. הפעלה: בתוכנית הראשית יוצרים AppDomain בעזרת AppDomain.CreateDomain עם שם ידידותי. על האובייקט הזה קוראים ל-ExecuteAssembly עם שם הקובץ ומערך הארגומנטים, והערך המוחזר נשמר.
8. הרס: AppDomain.Unload מוריד את הדומיין.
9. שם מחלון: שני הקבצים משתמשים באותו חלון קונסול. לכן שינוי של הכותרת בחלק אחד דורס את הכותרת שהוגדרה קודם.
הרצת DLL ו-Serializable מול MarshalByRefObject
10. יצירת אובייקט בדומיין אחר: CreateInstanceFromAndUnwrap יוצר אובייקט מטיפוס שנמצא ב-DLL, בתוך הדומיין שנבחר.
11. Serializable: אם המחלקה מסומנת כ-serializable היא מועתקת לדומיין הראשי, ולא נשארת בדומיין השני. לכן שינוי של האובייקט לא נראה בדומיין הראשי.
12. MarshalByRefObject: מחלקה שיורשת ממנו נשארת בדומיין שבו נוצרה, והדומיין הראשי עובד מולה דרך רפרנס. בהדגמה האובייקט נשאר בדומיין השני.
העברת נתונים בין דומיינים
13. SetData ו-GetData: AppDomain.SetData שולח זוג מפתח-ערך לדומיין השני, ובתוכו AppDomain.CurrentDomain.GetData קורא אותו.
14. טיפוסים שונים: עם struct בלי serializable נוצר עותק פשוט, עם מחלקה שיורשת MarshalByRefObject שינוי מופיע בדומיין הראשי, ומחלקה serializable נשארת כעותק.
15. אירועים: AppDomain מאפשר להירשם ל-AssemblyLoad, ל-FirstChanceException ול-DomainUnload, וכך לדעת מה קורה בתוכו.
כל דומיין מבודד את הזיכרון שלו, ורק העברה מפורשת של נתונים מאפשרת תקשורת ביניהם.
השיעור הבא בקורס: תרגילים על AppDomain

פרקי ההרצאה: AppDomains

  1. 00:00

    מהו AppDomain ב-.NET

  2. 01:14

    Process, Threads וטעינת Assembly

  3. 04:09

    סיבות לפתיחת AppDomain נפרד

  4. 06:06

    החלפת מידע בשרת עם AppDomain שני

  5. 08:18

    טעינת קובץ EXE של תוכנת עזר

  6. 09:38

    בניית תוכנת Calculator כ-EXE

  7. 13:55

    הרצת ה-EXE מתוכנה אחרת

  8. 14:51

    יצירת AppDomain עם CreateDomain

תמלול ההרצאה: AppDomains

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

  1. 00:03

    אנחנו מגיעים לנושא אחר לגמרי והנושא הזה נקרא App Domains. App Domain מהמילה Application Domain כאשר Domain זה תחום או טווח נפרד.

  2. 00:18

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

  3. 00:41

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

  4. 00:57

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

  5. 01:16

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

  6. 01:32

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

  7. 02:08

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

  8. 02:20

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

  9. 02:44

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

  10. 03:02

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

  11. 03:18

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

  12. 03:41

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

  13. 03:57

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

  14. 04:12

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

  15. 04:36

    לבצע איזושהי הבדלה בין הזיכרון שהוא משתמש לבין הזיכרון שלנו. נניח הורדנו את ה-DLL הזה כ-third-party component, איזשהו רכיב של איזושהי חברה אחרת ואנחנו רוצים לבצע הפרדה, לא רוצים שהוא יתערבב לנו בזיכרון, ואז אנחנו יכולים ליצור אפ דומיין נפרד, לטעון לתוכו את אותו

  16. 04:58

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

  17. 05:19

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

  18. 05:36

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

  19. 05:49

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

  20. 06:04

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

  21. 06:21

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

  22. 06:38

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

  23. 06:50

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

  24. 07:13

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

  25. 07:36

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

  26. 07:56

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

  27. 08:15

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

  28. 08:37

    זה לא קובץ Execution שמיועד לשימוש על ידי הלקוח. אם ישנו קובץ Execution שעושה איזה פעולה ומיועד לשימוש על ידי תוכנות אחרות, אפשר להריץ אותו דרך ה-Command Line ואפשר להריץ אותו דרך תוכנה אחרת.

  29. 08:53

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

  30. 09:15

    דבר ראשון, בגלל שיש לי פה שתי תוכנות שונות, מה שאני הולך לעשות זה לפתוח solution break ונקרא לו Load אקזה in a different app domain.

  31. 09:34

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

  32. 09:53

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

  33. 10:10

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

  34. 10:35

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

  35. 10:55

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

  36. 11:26

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

  37. 11:52

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

  38. 12:09

    במידה ושלחו לנו את האופרטור פלוס, אנחנו רוצים להכניס לריזולט את ה-first number ועוד ה-second number. במידה והכניסו לנו אופרטור מינוס, אנחנו רוצים לבצע את הפעולה של החיסור.

  39. 12:36

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

  40. 13:24

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

  41. 13:42

    אז אנחנו רוצים עכשיו תוכנה אחרת שתוכל להריץ את ה-execution הזה אז בואו נצרף נלך ל-solution נוסיף new project שוב פעם אנחנו בקונסול אפליקיישן וזה בעצם התוכנית הראשית שמתחילה את כל התהליך.

  42. 14:12

    נקרא לה Main Assembly. אנחנו רוצים שה-Main Assembly יהיה הראשון שירוץ, לכן נגדיר אותו כ-Start-up Project. כעת אנחנו רוצים להשתמש בתוכנית השנייה, בואו נצרף אותה ל-References, Add Reference.

  43. 14:29

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

  44. 14:46

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

  45. 15:06

    ככה אנחנו יוצרים לעצמנו אפ דומיין נפרד. הדבר שאנחנו צריכים לתת לפונקציה קריאי דומיין זה משהו שנקרא Friendly Name. זה רק שם שניתן לזהות את האפ דומיין שלנו, אנחנו יכולים לקרוא לזה בכל שם, נקרא לו My Calculator.

  46. 15:28

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

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

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

ההרצאה הבאה: תרגילים על AppDomain

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

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