PDA

View Full Version : سوال: چگونه می توان با استفاده از نخ ها اطلاعاتی را در دیتا گرید ویو قرار داد؟



rasol_afkham
سه شنبه 11 آذر 1393, 14:46 عصر
با سلام خدمت دوستان عزیز::لبخند:
فرض کنید بر روی فرم برنامه کنترل دیتا گرید ویو داریم و می خواهیم با استفاده از نخ ها اطلاعاتی را در دیتا گرید ویو قرار دهیم. بدون اینکه برنامه به حالت انجماد برود. چطور باید اینکار را انجام داد.
قبل از ایجاد این تاپیک در انجمن گشتم و پستهایی رو پیدا کردم ولی چیز مفیدی توش نبود، البته PDF هایی هم درباره Threading از اینترنت دانلود کردم، که واقعا چیزی ازش نفهمیدم. از چند تا سایت هم چند تا آموزش تصویری از Threading گرفتم و دید. بد نبود ولی انقدر پیش پا افتاده و مقدماتی بود که اصلا نمی شد چیز زیادی ازش یاد گرفت.
در ضمن یکی از بیشترین خطاهایی که در زمان استفاده از Thread گرفتم و کلی هم گشتم تا بدونم چطور باید کد ها رو نوشت تا این چنین خطایی بوجود نیاد رو هم نیافتم در زیر قرار دادم.

Cross-thread operation not valid: Control 'label1' accessed from a thread other than the thread it was created on.

rasol_afkham
چهارشنبه 12 آذر 1393, 10:30 صبح
جواب سوال را با کمی جستجوی بیشتر پیدا کردم. برای دوستانی که همچنین مشکلی دارند، می تونید به وب سایت
http://learnfiles.com/
بروید و فیلم آموزش Multi_Threading_in_CSharp رو دانلود کنید. داخل اون آموزش توضیح داده چطور می توان چنین خطایی رو مدیریت نمود.

rasol_afkham
چهارشنبه 12 آذر 1393, 11:39 صبح
خطای Cross-thread operation not valid: خطای خیلی معروفی است. و در لینک زیر توضیحاتی درباره مدیریت این خطا اومده

http://msdn.microsoft.com/en-us/library/ms171728%28v=vs.80%29.aspx

اما در زیر من درباره کدی که نوشتم و طریقه رفع خطاش هم توضیح می دم. از دیروز صبح تا حالا داشتم تو اینترنت می گشتم تا بلاخره امروز جوابش رو پیدا کردم. به همین خاطر هم این پست رو تکمیلش کردم برای دوستانی که می خواهند از Thread ها در برنامه هاشون استفاده کنن.
اول درباره کاری که می خوام انجام بدم توضیح می دم. من تو برنامم یه فایل دارم که 10000 رکورد داخلش قرار داره. این رکوردها داخل بانک SQL نیست، داخل یه فایل که خودم اون رو ایجاد کردم. برنامه به این صورت کار می کنه. اول رکوردها رو از فایل می خونه و داخل یک آرایه از نوع Collection قرار میده. بعد اطلاعات رو داخل یک کنترل DataGridView قرار می ده برای نمایش.
من اطلاعات رو مستقیم از فایل داخل DatGridView قرار ندادم و اول اون رو داخل آرایه قرار دادم. به این خاطر که اگر می خواستم 10000 رکورد را از فایل بخونم و همزمان در DataGridView قرار بدم، خوب با سرعت خیلی کمی این کار رو می کرد. این پست رو ببینید می فهمید (http://barnamenevis.org/showthread.php?477719-%DA%86%D8%B7%D9%88%D8%B1-%D9%85%DB%8C-%D8%AA%D9%88%D8%A7%D9%86-%DA%86%D9%86%D8%AF%DB%8C%D9%86-%D8%B1%D8%AF%DB%8C%D9%81-%D8%AC%D8%AF%DB%8C%D8%AF-%D8%B1%D8%A7-%D8%A8%D9%87-DataGridView-%D8%A8%D8%A7-%D8%B3%D8%B1%D8%B9%D8%AA-%D8%A8%D8%A7%D9%84%D8%A7-%D8%A7%D8%B6%D8%A7%D9%81%D9%87-%D9%86%D9%85%D9%88%D8%AF%D8%9F)
چون سرعت قرار دادن رکوردها در DataGridView پایین است اومدم و از Thread برای قرار دادن اطلاعات داخل DataGridView استفاده کردم. اما استفاده از Thread در حالت غیر حفاظت شده خطای معروف
Cross-thread operation not valid
رو تولید می کنه. یعنی شما نمی توانید از کنترلی که در Threadی دیگر ایجاد شده در این Thread استفاده نمایید. اما برای مدیریت این خطا باید از خصوصیت InvokeRequired و متد Invoke کنترل مورد نظر استفاده نمایید تا برنامه اجازه دستری کنترلی را در Threadی غیر از Threadی که ایجاد شده رو بده.

کد های برنامه به صورت زیر هستند

for (int i = 0; i < Pass.Count; i++)
{
if (dgvPass.InvokeRequired)
{
dgvPass.Invoke((MethodInvoker)delegate()
{
dgvPass.Rows.Add(i + 1,
Pass.Position,
Pass.ID,
Pass[i].FirstName,
Pass[i].LastName,
Pass[i].Phone,
Pass[i].Mobile,
Pass[i].Date,
Pass[i].Address);
});
}
}

در کد بالا [I]Pass نام آرایه ای است که اطلاعات در آن قرار دارند و dgvPass نام DataGridView‌ است که قرار است اطلاعات را نمایش دهد.
حتما فراموش نکنید که قبل از فراخوانی [I]Thread‌ خصوصیت IsBackground اون رو برابر با true‌ قرار دهید و یا با اتمام کار و یا خروج از برنامه Thread مورد نظر را از بین ببرید. در غیر اینصورت با بسته شدن برنامه Thread کماکان به کار خود ادامه می ده تا یه خیری پیدا بشه و اون رو ببنده.