שאלה בקשר ל .Net Timer

Adidi70

New member
שאלה בקשר ל .Net Timer

האם יש איזושהיא דרך לקבוע עדיפות (priority) של Timer ? אני מנסה להכניס timer באפליקציה שלי ב Vb.net והוא משום מה לא עובד חלק- ה interval שלו הוא 1 (המהירות הכי מינימלית) ואני מנסה להזיז תווית כל הזמן בפיקסל אחד בכל ארוע ה Tick של ה Timer הבעיה היא שהמהירות נשארת אותה מהירות אם אני אשנה את ה interval ל 5 או ל 10 - כלומר שבמהיריות ממש גבוהות (שה interval ממש קטן) אין לזה משמעות עוד דבר בהתחלה של הפעלת ה timer אני רואה שהתווית זזה לי מהר ופתאום היא מאטה מהירות עד סוף התנועה שלה ! מישהו יודע אם יש איזשהוא מאפיין או בעיה ב timer עם מהירות כאלה קטנות ??
 

gilad g

New member
תשובות

העין האנושית אף פעם לא תראה את ההבדל שבין מילישניה אחת לחמש מילישניות, ולכן זה נראה לך כאילו אין להפרש משמעות. בקשר להאטה של המהירות - תבדוק את הקוד שלך, יכול להיות שיש משהו בקוד שלך שמאט את הטיימר (כגון אלגוריתם איטי או לולאה ארוכה מידי). הבעיה עם timer במהירויות גבוהות הוא שטיימר פה פשוט לא מתאים. כדי להזיז תוית בפיקסל אחד, תשתמש ב-Threads, ולא בטיימרים. Thread הוא חלק של התוכנית שרץ במקביל לשאר התוכנית, כדי לא להפריע לתוכנית הראשית בפעולתה. יש לך דוגמא פה: http://www.dotnetextreme.com/code/Threading.asp
 

Adidi70

New member
זה מה שעשיתי בסוף...

אבל עדיין אתה צריך לא לשכוח לקבוע את העדיפות של ה Thread ל Highest אחרת התנועה אינה חלקה - וזה הסיבה גם שב Timer התנועה האטה לי ולא היתה חלקה - אין לי שם כמעט קוד בתוך הtimer - כמו שאמרתי אני רק משנה לתווית את מאפיין ה Location Y בפיקסל אחד זה הכל אז זה לא נכון ש timer לא מתאים כאן - Timer עובד בדיוק כמו Thread רק למשימות מתוזמנות - הבעיה היא של timer לא ניתן לקבוע priority כמו ל Thread והוא בא עם Normal Priority שכאמור לא מספיקה כדי לגרום ל thread להתנהג כמו timer צריך להתחכם וליצור לולאה אינסופית עם הפוגות של מאפיין Sleep של ה timer - יותר ברור למתכנתי Java
אני אשמח לפרט באם יהיה צורך (אגב זה אני "פגני" מעכשיו אני אהיה בפורום בשם הזה)
 

Adidi70

New member
הסבר...

Thread - משמש לבצע משימה או משימות ללא תלות במשימות האחרות שבתוכנית באופן סינכרוני לחלוטין. Timer - הוא סוג של Thread שמשמש לאותה מטרה רק למשימות מתוזמנות שמתרחשות בפרקי זמן קבועים. לכל Thread (ובתוך זה גם ל Timer) יש עדיפות (Priority) שאיתה הוא פועל בהתאם לתוכניות אחרות - למשל Highest Priority תגרום לתוכנית להקצות את רוב המשאבים לביצוע אותו Thread ולכן לפעילות יותר חלקה ומיידית של משימותיו כמו כל אובייקט מובנה ה Timer הוא מוגבל בכך שלמשמתמש אין גישה לכל המאפינים שיש ל Thread (אני מניח שה timer בא עם deafult normal Priority - ניתן למצוא ב system.Threading.ThreadPriority) ולכן מחלקת Thread היא יותר גמישה ובמקרה שלי גרמתי לה להתנהג כמו Timerע"י כך ששמתי את המשימה שלי בתוך לולאה אין סופית ובסוף הלולאה לאחר ביצוע אותה משימה השתמשתי במאפיין Sleep של הטיימר (שמשהה את פעילותו בכך וכך זמן שהוא מקבל בmillisecond) בזמן של 1 millisecond וכך נוצרה לי משימה שמתבצעת בפרקי זמן קבועים (Sleep) באופן מחזורי (לולאה אינסופית) באופן נפרד משאר התוכנית (משימה של אובייקט ה Thread שיצרתי)
 

gilad g

New member
../images/Emo45.gif

מפתיע אותי, שאין אפשרות לגשת אל ה-Thread של אותו טיימר (ע"י איזשהו מאפיין protected, או משהו כזה..)
 

yuval k

New member
ודרך אגב, אני מאוד ממליץ לך

לא להשתמש בלולאה אינסופית ב-thread הנ"ל: אתה צריך איכשהו להפסיק את זה, ואם תשים בתנאי משתנה ולא פשוט true, תוכל לגרום לעצירה באיטרציה הבאה. זאת, כמובן, אם לא עשית את זה עדיין
 

yuval k

New member
נו, כן, אבל עדיין.

מה שקורה זה שנזרקת exception, ויותר נחמד פשוט לעצור אותו, ולא ע"י העפת ה-thread; ואחרי שהוא עוצר, מעיפים את ה-thread. לא יודע, לי זה נראה נקי יותר
 

Adidi70

New member
לא נזרק שום exeption !

ברגע שאתה קורא לשיטה Abort של ה Thread - הוא פשוט מוציא אותך מהפונקציה (שכוונה ע"י ה AdressOf) לא חשוב מה יש בתוך הפונקציה
 

gilad g

New member
יובל

אני עדיין חושב שהשיטה שלך עדיפה - א. בגלל ה-Exception, שכנראה, כן נזרק (לא ממש בדקתי את זה) ב. בגלל שה-Thread שלך יכול לעצור בשלב לא ידוע. לדוגמא, אם בתוך ה-Thread אנחנו מנקים unmanaged resources, יכול להיות לזה השפעות רציניות - זליגות זכרון, וכו' - כי הפקודות של הניקוי יכולות שלא להיקרא בגלל עצירתו של ה-Thread באמצע. לפיכך, עדיף לחכות שה-Thread יסיים את עצמו, ולסיים הכל בצורה נקייה באמצעות Join.
 

nattygur

New member
כן מוכר, עדיף להשתמש ב Timer

של MultiMedia. זה לא Managed קוד (עדיין... כן ב LongHorn) אבל קל לשלב את ה API.
 

Adidi70

New member
שאלה חדשה בקשר ל Form KeyDown

ברגע שיש לי כפתור בתוך Form ואני רוצה לגשת לארוע KeyDown של ה Form הארוע לא עובד לי כיוון שהפוקוס הוא על הכפתור באופן אוטומטי ואז בעצם שאני לוחץ על כל מקש במקלדת זה מתייחס לארועי לחיצת מקשים של הכפתור !! מישהו מכיר את הבעיה הזו ? איך אני יכול להעביר את הפוקוס או לחילופין שיטה אחרת שתעזור לי לעבוד באופן נורמלי עם keyDown של Form למרות שיש עליו עוד Components !
 

gilad g

New member
המממ

הנה מה שיש לMSDN לומר בנידון:
To handle keyboard events only at the form level and not allow other controls to receive keyboard events, set the KeyPressEventArgs.Handled property in your form's KeyPress event-handling method to true. Certain keys, such as the TAB, RETURN, ESCAPE, and arrow keys are handled by controls automatically. In order to have these keys raise the KeyDown event, you must override the IsInputKey method in each control on your form. The code for the override of the IsInputKey would need to determine if one of the special keys is pressed and return a value of true.​
אבל, בדקתי את העניין וזה לא ממש עובד
אם זה עובד בשבילך, או אם פתרת את זה בדרך אחרת - אני אשמח לשמוע
 

Adidi70

New member
לא - אני לא מצליח

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

gilad g

New member
תנסה את KeyPreview

http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemWindowsFormsFormClassKeyPreviewTopic.asp?frame=true
 

Adidi70

New member
שאלה חדשה - אז ככה...

יש לי Panel ואני שם ב- Design כבר תמונה מקובץ מסוים במחשב על כל ה Panel - אני משתמש ב Timer (או Thread-לא ממש משנה) להזיז Label שעל ה Panel (ליצור תנועה מתמשכת) ואחרי כל הזזה אני קורא לשיטה Refresh של ה Panel כמובן כדי לרענן אותו ולהציג את המיקום החדש של ה Components שעל ה Panel. הבעיה שלי (וזה קשור לבעיה שהעליתי קודם) היא שה Timer עובד באיטיות מאוד - ועכשיו גיליתי למה - השיטה Refresh צורכת מה Thread כנראה משאבים רבים - בלי לקרוא לשיטה ה timer יעבוד טוב אך הציור לא יהיה חלק ! מכיוון שאני קורא לשיטה refresh ה Panel מצייר מחדש את כל מה שעליו כולל את התמונה שהעליתי קודם לתוכו - אם אני משתמש בצבע רגיל לצביעת ה Panel הכל עובד חלק !!! הבעיה היא שהוא מצייר שוב ושוב את התמונה גם (דבר שאין לי בו צורך) וזה מאט מאוד את הפעילות!! איך אני יכול לגרום לו לצייר רק את האובייקט שמשתנה (ולא את הרקע!!) או בגדול איך אני יכול לפתור את זה ??
 

gilad g

New member
הממ

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