PDA

View Full Version : سوال: اجراشدن یک رویداد بعد از کامل شدن یک ترد



Mrs.Net
جمعه 27 دی 1387, 22:24 عصر
یه ترد صدا میزنم که بصورت background کاری انجام بده
میخوام وقتی کار ترد انجام شد یه تابع صدا زده بشه. چجوری اینکارو باید بکنم؟

newgoldenman
شنبه 28 دی 1387, 00:20 صبح
سلام دوست عزيز
اين دقيقاً عين كاري هست كه من توي يكي از برنامه هام انجام دادم. خيلي ساده است انجام اين كار.
مواد لازم::لبخند:
يك عدد تايمر:
وقتي كه تردتون (مثلاً myThread)رو صدا ميزنيد و شروع به كار ميكنه، تايمرتون(myTimer) رو Start كنيد. (Intervalش رو نظر به صلاح خودتون تغيير بديد-من 100 گذاشتم-)

توي متد Tick تايمرتون اين كد رو بنويسيد:

if (myThread.ThreadState.Equals(ThreadState.Stopped))
{
myTimer.Stop();
//ToDo
}
به جاي

//ToDo
هر كاري كه دلتون ميخواد انجام بشه، بنويسيد. چون myThread كارش تموم شده.

موفق باشيد.

ahmadsystemco
شنبه 28 دی 1387, 07:49 صبح
سلام خدمت دوستان عزیز
این سوال برای من هم تقریبا پیش آمده.
اگر در Thread ای بجز Thread اصلی (Main Thread) تغییراتی در شکل و ظاهر کنترل ها بدهیم مثلا مقدار یک Progress Bar را تغیر بدهیم در هنگام دیباگ کردن خود VS خطای زیر را می دهد.


Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on.
معنی این خطا را فهمیدم ولی هنگامی که برنامه را در محیط ویندوز اجرا می کنم( بدون دیباگر VS) دیگر این خطا داده نمی شود و برنامه کار خود را انجام میدهد.
اما در حین ساختن پروزه دیکشنری خودم هنگامی که Thread ی را برای Load شدن دیتابیس دیکشنری اجرا می کنم (AsyncCallback) و می خواهم بعد از کامل شدن Thread یک تایمر در Main Thread اجرا کنم این کار انجام نشده و تایمر من اجرا نمی شود. (مثل این است که Thread دیگر مانند یک دنیای دیگر بوده یا یک بعد دیگر که تایمر من در آنجا اجرا می شود ولی تاثیری در برنامه اصلی ندارد)

از اساتید عزیز خواهشمندم در مورد این قضیه توضیحاتی داده و به بنده کمک کنند.

ببخشید که از تاپیک Mrs.Net استفاده می کنم.

با تشکر AHS

Mrs.Net
شنبه 28 دی 1387, 08:04 صبح
جناب newgoldenman ممنون اما این راه شما فقط کار شمارو انجام میدهد و بنظرم منطقی و صحیح نیست چون باید روش پیش بینی شده ای برای این منظور وجودداشته باشه که من دنبال اون روش هستم.

جناب ahmadsystemco وقتی برنامه اصلی شما اجرا میشه، داخل یک ترد که ترد اصلی هست صدا زده میشه و هر فرمی اجرا بشه توسط این ترد اجرا میشه. حالا اگه یه ترد جدید ایجاد کنید از نظر اصول نباید این دو ترد در کار یکدیگر (تغییرات در فرمهای ترد اول) دخالت کنند چون ترد فقط برای این ایجاد شده که مستقل از ترد اول کاری رو انجام بده. شما در حالت دیباگ این خطارو میبینید و درست هست. در حالت stand by دیگه این خطا به شما نشون داده نمیشه اما در واقع کار ترد هم با اشکال روبرو میشه گرچه نتیجه نهایی درست نشون داده میشه.

یه سری توابع wait و غیره تو نت پیدا کردم اما چیزی نفهمیدم لطفا اساتید راهنمایی کنند در مورد سوال من

ممنون

mpmsoft
شنبه 28 دی 1387, 10:41 صبح
به لینک زیر مراجعه کنید

http://www.albahari.com/threading/

Mrs.Net
شنبه 28 دی 1387, 11:10 صبح
به لینک زیر مراجعه کنید

http://www.albahari.com/threading/ (http://www.albahari.com/threading/)
لینک نگاه کردم اما جواب سوالم پیدا نکردم!
میخوام وقتی کار ترد تموم شد متن یک لیبل رو تغییر بدم و تا اون لحظه سیستم کارشو انجام بده.

ahmadsystemco
شنبه 28 دی 1387, 13:59 عصر
سلام
Mrs.Net از توضیحتان متشکرم. ولی چگونه می توانم بین Thread ها ارتباط ایجاد کنم. مثلا در یک Thread کاری را انجام دهم و با انجام شدن هر مر حله از کار مقدار پیشرفت کار را به اطلاع کاربر که در Thread اصلی است برسانم؟

با تشکر AHS

Mahdi.Kiani
شنبه 28 دی 1387, 15:54 عصر
سلام
Mrs.Net از توضیحتان متشکرم. ولی چگونه می توانم بین Thread ها ارتباط ایجاد کنم. مثلا در یک Thread کاری را انجام دهم و با انجام شدن هر مر حله از کار مقدار پیشرفت کار را به اطلاع کاربر که در Thread اصلی است برسانم؟

با تشکر AHS

از کنترل backgroundworker استفاده کنید. ( لطف کنید سوالات مختلف را در تاپیک های جدا گانه بپرسید)

newgoldenman
شنبه 28 دی 1387, 16:08 عصر
جناب newgoldenman ممنون اما این راه شما فقط کار شمارو انجام میدهد و بنظرم منطقی و صحیح نیست چون باید روش پیش بینی شده ای برای این منظور وجودداشته باشه که من دنبال اون روش هستم.
ممنون
بله. حق با شماست. اين روش فقط كار راه اندازه و منطقي نيست. منم مشكل شما رو داشتم، زياد گشتم، چون به راه حل ديگه اي نرسيدم، اين روش رو خودم پياده سازي كردم.
به هر حال، اگر راه حل ديگه اي نداشته باشه، اين يك روش عالي و بدون دردسر هست. چون برنامه هر لحظه بايد ترد مورد نظر رو چك كنه. يا شايدم اينطوري ميتونه باشه كه: وقتي كه هر ترد كارش تموم شد، يك مقدار به ترد اصلي و سازنده ي آن ترد بفرسته...

بهر حال، تاپيك جالبيه.
موفق باشيد.

RED-C0DE
شنبه 28 دی 1387, 19:40 عصر
این مقاله رو حتما ببینید :
http://www.codeproject.com/KB/cs/AsyncMethodInvocation.aspx

اینجا رو هم (توی چند پست قبلی به یه page ِ دیگش اشاره شده بود) :
http://www.albahari.com/threading/part3.aspx#_Asynch_Delegates

می تونین از Pattern هایی که برای این قبیل کارها تعریف کردن پیروی کنین مثل :

Asynchronous Design Pattern Overview
http://msdn.microsoft.com/en-us/library/aa719595(VS.71).aspx
http://www.codeproject.com/KB/dotnet/async_pattern.aspx

و یا
Event-based Asynchronous Pattern Overview
http://msdn.microsoft.com/en-us/library/wewwczdw.aspx

RED-C0DE
شنبه 28 دی 1387, 19:45 عصر
این هم یه برنامه که بعد از اتمام یک کار زمانبر روی یک Thread ِ دیگه، متن داخل Label داخل فرم رو تغییر می ده :

hosein.jozi
پنج شنبه 22 اسفند 1387, 13:17 عصر
سلام خدمت دوستان عزیز
این سوال برای من هم تقریبا پیش آمده.
اگر در Thread ای بجز Thread اصلی (Main Thread) تغییراتی در شکل و ظاهر کنترل ها بدهیم مثلا مقدار یک Progress Bar را تغیر بدهیم در هنگام دیباگ کردن خود VS خطای زیر را می دهد.


Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on.
معنی این خطا را فهمیدم ولی هنگامی که برنامه را در محیط ویندوز اجرا می کنم( بدون دیباگر VS) دیگر این خطا داده نمی شود و برنامه کار خود را انجام میدهد.
اما در حین ساختن پروزه دیکشنری خودم هنگامی که Thread ی را برای Load شدن دیتابیس دیکشنری اجرا می کنم (AsyncCallback) و می خواهم بعد از کامل شدن Thread یک تایمر در Main Thread اجرا کنم این کار انجام نشده و تایمر من اجرا نمی شود. (مثل این است که Thread دیگر مانند یک دنیای دیگر بوده یا یک بعد دیگر که تایمر من در آنجا اجرا می شود ولی تاثیری در برنامه اصلی ندارد)

از اساتید عزیز خواهشمندم در مورد این قضیه توضیحاتی داده و به بنده کمک کنند.

ببخشید که از تاپیک Mrs.Net استفاده می کنم.

با تشکر AHS


من برای حل این مشکل در برنامه شما کد شما رو اینگونه تغییر دادم


this.Invoke((MethodInvoker)delegate
{
remembererToolStripMenuItem.Enabled = true;
});

هر جای دیگه هم خطا میده همین کار رو بکن