הצגת שעון מדויק ב WPF

RotemR10

New member
הצגת שעון מדויק ב WPF

היי,

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

יש רעיונות נוספים\אפשרויות לטעויות שאני עושה?

תודה רבה!
 

ziv1f

New member
DateTime?

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

בברכה,
זיו
 

RotemR10

New member
נכון, אבל כמו שאמרת

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

תודה רבה על תגובתך
 

spiritus asper

New member
השעון של Windows לא כל כך מדוייק

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

spiritus asper

New member
מעבר לזה

לקרוא ישירות ל-DateTime.Now הוא בדרך כלל רעיון רע בגלל סיבות של הזזת שעות בסגנון שעון קיץ וכו'... אלטרנטיבה עדיפה תהיה להשתמש ב-DateTime.UtcNow (או, לדגום stopwatch ולהוסיף את הזמן שחלף לעוגן זמן שנדגם בעזרת UtcNow).
 

spiritus asper

New member
לא

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

EdotK

New member
(stopwatch בשביל להציג שעון? השתגעתם?)

DateTime בשביל לשאול מה השעה. DispatcherTimer בשביל לתזמן.

spiritus - כשמשתמשים ב DispatcherTimer לא משתמשים בטיימר של מערכת ההפעלה, אלא משתמשים בלופ ההודעות הראשי של WPF, שהוא מאוד מאוד מהיר והרבה יותר מדויק מטיימר רגיל. בנוסף, היות ו Dispatcher == UI Thread, אין כאן אפילו פתיחת ת'רד נוסף, ולפיכך גם אין צורך בנסכרון ת'רדים.
 

RotemR10

New member
אז יש לך רעיון אולי

למה שימוש ב DispatcherTimer גורם אצלי ל delay מאוד משמעותי?
 

EdotK

New member
DispatcherTimer משמש כשעון האנימציות של WPF

אנימציות ב WPF מגיעות בקלות ל 200 fps שזה 5ms
 

spiritus asper

New member
Stopwatch מגיע לפחות ממילי

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

EdotK

New member
זה overkill היסטרי. השואל המקורי דיבר על UI

בUI אין שום טעם *אף פעם* להראות משהו יותר מהר מ 60 fps (שזה בערך 18ms), וגם אז לא צריך שזה יהיה מדויק.
 

ziv1f

New member
את בטוחה שזה השימוש ב-DispatcherTimer ?

שגורם לכל הבעיות?

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

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

בברכה,
זיו
 

RotemR10

New member
אני חושבת שכן,

כי כשאני משתמשת ב thread רגיל במקום ב DispatcherTimer ה delay הרבה יותר קטן.
בהחלט הגיוני מה שאתה אומר, אבדוק זאת ואעדכן.

תודה
 

RotemR10

New member
בדקתי:

אני מפעילה את הטיימר כל 10 מילי שניות (ומעדכנת את התצוגה כל שניה).

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

ואכן, יש שם קוד רב, אבל הוא די נצרך. (מה ז"א בדיוק קוד סינכרוני?
)

[אני מניחה שזה נושא רחב- "איך לכתוב טיימר שרץ בתהליך נפרד ולא 'מפריע' ל UI" או משהו כזה, אבל ממש אשמח להכוונה\לינקים\עצות מה בדיוק לחפש בגוגל\...]

תודה רבה לעונים, אתם עוזרים לי מאוד!
 

EdotK

New member
אז כנראה זה בכלל לא קשור לWPF, את צריכה ללמוד

איך לכתוב קוד א-סינכרוני בצורה נכונה.
 

thankful

New member
בדיוק היום בעבודה ניסיתי לראשונה להשתמש ב

Stopwatch... איזה צירוף מקרים...
זה אמנם לא ממש עזר לי במה שהייתי צריך, כי זמני המדידה לא היו רלוונטיים במקרה זה- אך הרווחתי ידע נוסף בתחום :)
 

RotemR10

New member
רק מעדכנת: פתרתי את הבעיה

הבעיה היתה בחלוקה לקויה לת'רדים- היה עומס רב מידי על הת'רד שמטפל ב UI מה שיצר את ה delay.

תודה רבה לכל העונים, הארתם את עיני
 
למעלה