نوشته شده توسط
combo_ci
سلام
من یه برنامه نوشتم که توی یکی از فرم هاش یک data grid رو fill میکنم. (برنامه رو با 2005 نوشتم ) .میخواستم توی اون فرم یه thread تعریف کنم که datagride توی اون thread پر شه.... اما با یه خطا مواجه شدم (عکس خطا رو ضمینه تاپیک کردم)......از background worker هم استفاده کردم.....اما بازم همون خطا رو داد....
میشه راهنماییم کنین که چطوری میشه با یه thread دیگه به یکی از control های فرم دسترسی داشته باشیم ....
سلام.
واقعیت اینه که وقتی شما یه Window جدید ایجاد می کنید، دیگه نمیتونید به اون Window از طریق thread های دیگه دسترسی پیدا کنید. هر تلاشی برای دسترسی به پنجره (یا هر کنترلی در main-thread) باعث میشه تا شما پیام cross-thread operation not valid رو بگیرید. متاسفانه مایکروسافت در عین ناباوری یه Property به اسم CheckForIllegalCrossThreadCalls روی کنترل گذاشته که اگه اونو false کنید، دیگه این Checking انجام نمیشه و به نظر مشکلی پیش نمیاد. اما این روش صحیحی برای پیاده سازی cross-threading access نیست. چون شما از BackgroundWorker استفاده می کنید، من هم طرز استفاده صحیح از این کلاس رو بهتون می گم، و الا در بقیه موارد (مثل استفاده از Thread و ...) باید روشهای دیگه ای رو در پیش بگیرید. در واقع کاری که شما می خواهید انجام بدید و زمانگیر هستش، دریافت اطلاعات از سرور (یا بانک، بسته به نوع طراحی) هستش؛ نه پر کردن DataGrid. در نتیجه شما در Event DoWork باید اطلاعات رو از سرور دریافت کنید، و هر از گاهی اون اطلاعات رو به Grid اضافه کنید (مثلا هر 100 ردیف یکبار). Pseudo Code زیر مفهوم چیزی رو که گفتم بهتر نشون میده:
OnDoWork(...)
{
while(data to be fetched, exists)
{
data = GetOneHundredRowsFromDataSource();
ReportProgress(0, data);
}
}
private void OnProgressChanged(object sender, ProgressChangedEventArgs e)
{
//This methods is called in the main-thread context...
data = e.UserState;
addDataToTheGridControl();
}
به این ترتیب وقتی شما تابع ReportProgress رو دز DoWork صدا میزنید، در واقع باعث میشید تا اطلاعات مورد نطرتون (که در پارامتر دوم این تابع بهش میدید) به main-thread برنامه، marshal بشه و در دسترس قرار بگیره. به این ترتیب، متود OnProgressChanged (وProgressChanged event) صدا زده میشه و شما میتونید در این متود بدون نگرانی به کنترلهای main-thread (و از اون جمله Grid Control) دسترسی پیدا کنید.