עבור לתוכן

Cross thread invalid operation exception

Featured Replies

פורסם

Cross thread invalid operation exception נגרם כתוצאה מהעלאת event של FileSystemWatcher.

כאשר ה UI תופס את ה event ומנסה לעשות משהו (גם אם נתפס ע"י מישהו אחר ולאחר מכן מתחילה סדרה של קריאות לפונקציות כאשר מגיעים ל UI נזרק אקספשיין)

פתרון שקיים שימוש ב invoke או שימוש SynchronizingObject

delegate void CrossThreadOp(object param);

private void ChangeControl(object param)
{
if (InvokeRequired)
{
Invoke(new CrossThreadOp(ChangeControl), param);
}
else
{
// Change controls here
}
}

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

יש את הפתרון של Invoke, אך הפתרון מפריע לי מכמה סיבות:

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

2. זה נראה לי לא נקי לכתוב את זה בתחילת כל פונקציה של ה GUI.?

אשמח לתשובות ולהצעות.

פורסם

תערוך את ההודעה ושים את הקוד שלך בתג קוד, כדי שיהיה יותר קריא (מה זה סקוד?)

פורסם

בכדי להקל על קריאה למתודות בין הליך אחר להליך ה-UI הייתי ממליץ להשתמש

במחלקת ה-SynchronizationContext:

http://www.codeproject.com/KB/threads/SynchronizationContext.aspx

לדעתי היא הרבה יותר נוחה ולא מצריכה את העניין של הוספת שורות ה-Invoke.

פורסם
  • מחבר

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

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים