نمایش نتایج 1 تا 13 از 13

نام تاپیک: استفاده از دو thread در برنامه

  1. #1
    کاربر دائمی آواتار combo_ci
    تاریخ عضویت
    تیر 1384
    محل زندگی
    مشهد
    پست
    459

    استفاده از دو thread در برنامه

    سلام
    من یه برنامه نوشتم که توی یکی از فرم هاش یک data grid رو fill میکنم. (برنامه رو با 2005 نوشتم ) .میخواستم توی اون فرم یه thread تعریف کنم که datagride توی اون thread پر شه.... اما با یه خطا مواجه شدم (عکس خطا رو ضمینه تاپیک کردم)......از background worker هم استفاده کردم.....اما بازم همون خطا رو داد....


    اینم عکس خطا :



    میشه راهنماییم کنین که چطوری میشه با یه thread دیگه به یکی از control های فرم دسترسی داشته باشیم ....

  2. #2
    نقل قول نوشته شده توسط 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) دسترسی پیدا کنید.

  3. #3

  4. #4
    کاربر دائمی آواتار combo_ci
    تاریخ عضویت
    تیر 1384
    محل زندگی
    مشهد
    پست
    459
    خیلی ممنونن از راهنماییتون دوستان

    آخه این مشکل تنها توی کارهای data base به وجود نمیاد ....من یه برنامه دیگه هم نوشته بودم که توش یه فیلم رو لود میکردم....چون عمل لود کردن فیلم یه کم طولانی بود میخواستم اووونو توی یه thread جداگانه بزارم که باز با همین خطا مواجه شدم.....واقعا گیج شدم

    از این مثال دوست خوبم آقای علیرضا صالحی که تو code project بود چیز زیادی نفهمیدم ......میشه یه win app کوچولو که از اون کد استفاده کردین اینجا بزارین ؟

  5. #5
    کاربر دائمی آواتار ARA
    تاریخ عضویت
    آبان 1383
    محل زندگی
    Bad Sector
    پست
    448

    Cool

    مشکل cross thread همونطوری که تو پیغام error نوشته فقط باید چک کردن اون رو در لود فرم false کنی


    form1.CheckForIllegalCrossThreadCalls = false;


  6. #6
    نقل قول نوشته شده توسط combo_ci مشاهده تاپیک
    خیلی ممنونن از راهنماییتون دوستان

    آخه این مشکل تنها توی کارهای data base به وجود نمیاد ....من یه برنامه دیگه هم نوشته بودم که توش یه فیلم رو لود میکردم....چون عمل لود کردن فیلم یه کم طولانی بود میخواستم اووونو توی یه thread جداگانه بزارم که باز با همین خطا مواجه شدم.....واقعا گیج شدم

    از این مثال دوست خوبم آقای علیرضا صالحی که تو code project بود چیز زیادی نفهمیدم ......میشه یه win app کوچولو که از اون کد استفاده کردین اینجا بزارین ؟
    لینک دوم رو با دقت بخونید بیشتر توضیح داده.اگر باز هم متوجه نشدید بگید مثال بزارم.


    نقل قول نوشته شده توسط ARA مشاهده تاپیک
    مشکل cross thread همونطوری که تو پیغام error نوشته فقط باید چک کردن اون رو در لود فرم false کنی


    form1.CheckForIllegalCrossThreadCalls = false;

    عزیزم بیکار نبودن که این رو گذاشتن، همینجوری که یه چیزی رو disable نمی کنند یه کم زحمت داره ولی اون لینک دوم رو که گذاشتم بادقت بخونید ، راه اصولی تری برای حل این مشکل وجود داره.

  7. #7
    کاربر دائمی آواتار ARA
    تاریخ عضویت
    آبان 1383
    محل زندگی
    Bad Sector
    پست
    448
    هر چیزی بهایی داره
    برای یک برنامه ساده خیلی مواقع نمی صرفه راه های سخت رو امتحان کرد ،چه بسا با سر در نیاوردن از اون کد از C#‎ بیزار بشیم و خسته شیم
    ولی با راههای ساده شروع کرده و مسئله های سخت تر را راحت تر میبینیم

    من کلی با اینها سرو کله زدم و راحت ترین راه رو براش گفتم شایددر یک برنامه ساده کسی نتونه بگیه که کجای این راه حل مشکل داره

    کسی هم که برنامه درست و حسابی بنویسه (سوءتفاهم نشه) تو این جور چیزا نیمونه

    ولی ممنون که یک راه هم شما پیشنهاد کردین

  8. #8
    کاربر دائمی آواتار combo_ci
    تاریخ عضویت
    تیر 1384
    محل زندگی
    مشهد
    پست
    459
    من توی vs 2003 چک کد زیر رو پیدا نکردم.....لطف میکنین راهنماییم کنین؟

    form1.CheckForIllegalCrossThreadCalls = false;

  9. #9
    کاربر دائمی آواتار ARA
    تاریخ عضویت
    آبان 1383
    محل زندگی
    Bad Sector
    پست
    448
    تو 2005 فقط جواب میده به نظرم تو 2003همچین مشکلی نداشیم

  10. #10
    کاربر دائمی آواتار combo_ci
    تاریخ عضویت
    تیر 1384
    محل زندگی
    مشهد
    پست
    459
    آقای صالحی لطف میکنین یه تیکه کد بزارین ( طبق همون مثالی که واسه multithread زدید که از یک delegate استفاده کردین) که یه data gride توی یه thread جدا گونه لود بشه
    ممنون

  11. #11
    نقل قول نوشته شده توسط combo_ci مشاهده تاپیک
    من توی vs 2003 چک کد زیر رو پیدا نکردم.....لطف میکنین راهنماییم کنین؟
    form1.CheckForIllegalCrossThreadCalls = false;
    سلام.
    متعجبم که چرا جوابی رو که دادم نخوندید و هنوز اصرار به انجام کار نادرست دارید.

    اولا، بودن یا نبودن یه feature در .net framework هیچ ربطی به نسخه کامپایلر نداره، در نتیجه جمله "من تو vs 2003 چک کردم و پیدا نکردم..." درست نیست. جای این جمله باید بگید "من این property رو تو dotnet framework 1 و 1.1 پیدا نکردم، فقط توی 2 دیدمش!".

    دوما، بادید عرض کنم که CheckForIllegalCrossThreadCalls رو گذاشتن چون تو dotnet framework 1 به اشتباه اجازه Illegal Cross Threading رو داده بودن. اگه این اشتباه صورت نمی گرفت، بحث backward compatibility هم پیش نمیومد، و در نتیجه هرگز چنین Property زشتی رو روی کنترل نمیدیدیم. در واقع در نسخه 1 و 1.1، دسترسی شما از یک thread به کنترلی در یک thread دیگه باعث بروز خطا نمی شد (منظورم خطای پیش بینی شده هستش) و چنین Property ای هم وجود نداشت. اما چون این مساله باعث شد تا خیلی از برنامه نویسهای بی تجربه مدام این عمل رو تکرار کنن، مایکروسافت تصمیم گرفت تا به محض تشخیص چنین فراخوانیهای نادرستی یه خطا throw کنه و ... در نتیجه برنامه نویس متوجه بشه که کاری که داره انجام میده صحیح نیست و روش درستی رو برای مارشالینگ اطلاعات بین دو thread انتخاب کنه. اگر به توضیح این Property در msdn هم نگاه کنید، بیشتر متوجه مساله میشید:

    "هنگامیکه thread ای به Property ها و متودهای کنترلی که در thread دیگری ایجاد شده دسترسی پیدا کند، اغلب دچار نتایج پیش بینی نشده ای می گردد. یک اشتباه متعارف در استفاده از thread ها، فراخوانی متودهایی است که به هندلهای یک کنترل در thread نامناسب دسترسی می یابد. Property ای CheckForIllegalCrossThreadCalls را true کنید تا بتوانید فعالیت thread فعلی را ساده تر شناسایی کنید".

    در donet framework 1 و 1.1 هم این مساله وجود داشت. یعنی شما هیچ ایرادی نمیدید در دستیابی به کنترلهایی در thread های دیگه، اما هر لحظه این امکان وجود داشت تا دچار "نتایج پیش بینی نشده" (مثل hang کردن برنامه، reset شدن app و ...) بشید.

    سوما، من به زبون شیرین فارسی براتون توضیح دادم که چطور از BackgroundWorker استفاده کنید ولی شما هنوز اصرار دارید تا به نحوی با حداقل فعالیت برنامه اتون رو به وضعیت running ببرید. (در حالیکه از Background Worker هم دارید به اشتباه استفاده می کنید). حالا با این کار، شما دو اشتباه رو تو برنامه اتون دارید مرتکب می شید، یکی استفاده نادرست از BackgroundWorker و دیگری بوجود آوردن شرائط ناشناخته در برنامه.

    حالا دیگه راه و چاه رو بلدید، اگرهنوز اصرار دارید که متغیر مربوطه رو false کنید که برنامه اتون کار کنه، خوب اینکارو بکنید و دعا کنید که هیچوقت دچار اون شرائط پیش بینی نشده نشید.

  12. #12
    کاربر دائمی آواتار combo_ci
    تاریخ عضویت
    تیر 1384
    محل زندگی
    مشهد
    پست
    459
    ای بابا چرا عصبانی میشید برادر

    من اصل برنامم تو 2003 هستش و برا اینکه نحوه کار background wroker رو چک کنم توی 2005 هم برنامه رو کامپایل کردم اما باز هم همون خطای 2003 رو داد.....شما یه بار تست بکنید حرف من رو اونوقت میبینید که توی .net framwork 1.1 هم همچین خطایی رخ میده ...البته توی 2005 هم با false کردن پراپرتی CheckForIllegalCrossThreadCalls هم اتفاق خاصی در برنامه رخ نمیده ....انگار که شما یک try ..catch بنویسید و توی catch هیچی ننویسید ....در واقع کار با این کار برنامه از خطای cross thread رد میشه

    http://msdn2.microsoft.com/en-us/library/ms171728.aspx

    این مثال آقای صالحی خیلی جالب قضیه رو توضیح داده بود ...اما من دقیقا متوجه نشدم که delegate به کار رفته توی اون برنامه می text box رو set میکنه.

    واسه همین گفتم که یه تیکه کد که من بفهمم یه data ride رو چه طوری با وجود اون delegate پر کرد

    ممنون

  13. #13
    نقل قول نوشته شده توسط combo_ci مشاهده تاپیک
    ای بابا چرا عصبانی میشید برادر

    من اصل برنامم تو 2003 هستش و برا اینکه نحوه کار background wroker رو چک کنم توی 2005 هم برنامه رو کامپایل کردم اما باز هم همون خطای 2003 رو داد.....شما یه بار تست بکنید حرف من رو اونوقت میبینید که توی .net framwork 1.1 هم همچین خطایی رخ میده ...البته توی 2005 هم با false کردن پراپرتی CheckForIllegalCrossThreadCalls هم اتفاق خاصی در برنامه رخ نمیده ....انگار که شما یک try ..catch بنویسید و توی catch هیچی ننویسید ....در واقع کار با این کار برنامه از خطای cross thread رد میشه

    http://msdn2.microsoft.com/en-us/library/ms171728.aspx

    این مثال آقای صالحی خیلی جالب قضیه رو توضیح داده بود ...اما من دقیقا متوجه نشدم که delegate به کار رفته توی اون برنامه می text box رو set میکنه. واسه همین گفتم که یه تیکه کد که من بفهمم یه data ride رو چه طوری با وجود اون delegate پر کرد

    ممنون
    سلام.
    من تو پست قبلی مگه توضیح ندادم که چه اتفاقی می افته اگه اونو false کنید؟ حتی یه پاراگرف از msdn رو هم واستون ترجمه کردم، که از اشتباه در بیایین، اونوقت بازم میگین "با false کردن CheckForIllegalCrossThreadCalls هیچ اتفاقی خاصی در برنامه رخ نمیده". کی اینو گفته؟ مدرکتون برای این حرف کجاست؟ چرا شایعه درست می کنید؟ فکر نمیکنید 4 نفر دیگه این نوشته شما رو بخونن به اشتباه می افتن، (اگر تحقیق نکنن)؟ خوب این چیو نشون میده؟ خودتون قضاوت کنید.

تاپیک های مشابه

  1. اجرای تابع با پارامتر به صورت یک Thread.
    نوشته شده توسط hdv212 در بخش C#‎‎
    پاسخ: 16
    آخرین پست: یک شنبه 17 خرداد 1394, 00:11 صبح
  2. پیاده سازی تایمر با استفاده از Thread
    نوشته شده توسط Ghasem Dehghani در بخش C#‎‎
    پاسخ: 18
    آخرین پست: شنبه 15 اردیبهشت 1386, 17:40 عصر
  3. ایجاد thread
    نوشته شده توسط mahtab_18 در بخش C#‎‎
    پاسخ: 1
    آخرین پست: سه شنبه 11 اردیبهشت 1386, 09:59 صبح

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •