Task Async: לולאה שמחזירה את התוצאות בצורה אסינכרונית
-
יש לי פונקציה שרצה על מערך של מילים (תוצאות חיפוש), ועל כל איבר במערך היא הולכת למקור ולוקחת משם את הקטע בו מופיעה המילה, כדי להציג אותו למשתמש.
אני רוצה שעל כל איטרציה בלולאה - התשובה תחזור מיד ותוצג בUI ולא יצטרכו לחכות עד שהלולאה תיגמר.
ראיתי בעבר שיש אפשרות לעשות זאת ע"י שימוש בTASK async אך אני לא מצליח למצוא בגוגל איך..
(וגם לא איפה ראיתי זאת..)
אם מישהו יודע איך - אשמח לשמוע.
תודה רבה!פורסם במקור בפורום CODE613 ב17/05/2016 23:27 (+03:00)
-
גישה לUI מTask כמו מטריד מחייבת קריאה לDispatcher. לכן גם yield לא יעזור כאן כי הUI יקפא עד לסיום הזרימה.
הנה קוד דוגמה:public ObservableCollection<int> Collection { get; set; } = new ObservableCollection<int>(); private void button_Click(object sender, RoutedEventArgs e) { Task.Run(() => getAll()); } void getAll() { for (int i = 0; i < 3; i++) { Thread.Sleep(1000); Dispatcher.Invoke(() => Collection.Add(i)); } }
אבל אכן מה שארכיטקט הצביע על מעלת הyield לעבד את התוצאה תוך כדי עיבוד השאר עוזר להפרדה בין לוגיקת הלולאה לבין הטיפול בתוצאת כל איטרציה, הנה שינוי להמחשה:
public ObservableCollection<int> Collection { get; set; } = new ObservableCollection<int>(); private void button_Click(object sender, RoutedEventArgs e) { Task.Run(() => { foreach (var item in getYield()) Dispatcher.Invoke(() => Collection.Add(item)); }); } IEnumerable<int> getYield() { for (int i = 0; i < 3; i++) { Thread.Sleep(1000); yield return i; } }
זה אכן הרבה יותר טוב שהמתודה שעושה את העבודה לא דואגת לבעיות הUI של WPF.
פורסם במקור בפורום CODE613 ב18/05/2016 00:22 (+03:00)