PDA

View Full Version : سوال: مشکل با thread در نشان دادن فرم؟؟



sajadjamalian
شنبه 25 دی 1389, 12:44 عصر
سلام دوستان:
من یه ترد ایجاد کردم که قراره یه فرم رو نشون بده و یه سری عملیات روی کنترل های این فرم انجام بده، ولی وقتی برنامه رو اجرا میکنم فرم رو نشون میده ولی با تموم شدن کار ترد فرم بسته میشه، من میخوام اولا وقتی فرم نشون داده میشه بتونم با این فرم کار کنم(یعنی قفل نشه) و بعد از تموم شدن کار ترد هم فرمم بسته نشه، کسی میدونه باید چیکار کنم؟ ممنون.

esmaeily-hosein
شنبه 25 دی 1389, 12:57 عصر
بایستی احتمالا از متد showDialog استفاده کنی ! یا بعد از show از یک waiting کمک بگیری

sajadjamalian
شنبه 25 دی 1389, 12:59 عصر
ممنون از توجهتون دوست عزیز:
میشه یه کم بیشتر توضیح بدید؟؟ ممنون.

prankster
شنبه 25 دی 1389, 13:20 عصر
بهتر است که کلیه عملیات وابسته به UI مثل باز و بسته کردن فرم ها در Thread اصلی برنامه انجام شود، در هر حال در صورتی که اصرار بر این کار دارید می توانید، به جای متد Show برای نشان دادن فرم از ShowDialog استفاده کنید، dialog ایجاد شده Thread را متوقف کرده و تنها زمانی که بسته شود برنامه به روتین اصلی بر می گردد.
از Application هم می توانید برای نشان دادن فرم 2 استفاده کنید:

Application.Run(new Form2());
در صورتی که در Thread ایجاد شده IsBackground برابر true باشد، فرم 2 ایجاد شده وابسته به فرم اصلی شده و با بستن فرم اصلی فرم 2 هم بسته خواهد شد و خطر وجود دو برنامه در حافظه را به همراه نخواهد داشت

sajadjamalian
شنبه 25 دی 1389, 13:21 عصر
سلام:
توی برنامه ای که نوشتم قراره وقتی فرمی که توی ترد هست رو بهم نشون داد در ادامه کار ترد یه سری کنترل به این فرمم اضافه بشه، حالا وقتی از showdialog استفاده میکنم فقط فرم رو بهم نشون میده و انگار بقیه کار ترد رو انجام نمیده،
میشه کمک کنید تا این مشکل برطرف بشه؟ ممنون.

prankster
شنبه 25 دی 1389, 14:09 عصر
دقیقا به همین دلیل هست که پیشنهاد می شود کلیه عملیات مربوط به UI درون Thread اصلی انجام شود. هنگامی که یک برنامه Windows Form اجرا می شود، توسط کلاس Application یک فرم به عنوان فرم اصلی معرفی می شود، کلاس Application روی Thread اصلی waiting اجرا می کند و مادامی که فرم اصلی برنامه باز است، Thread اصلی پایان نیافته و کماکان فعل است. زمانی که یک Thread به انتهای فعالیت خود رسید، توسط Net. اصطلاحا dispose شده و در صورتی که مربوط به ThreadPool باشد دوباره به ThreadPool برمی گردد.
بنابراین شما برای جلوگیری از اتمام Thread جدید *باید* به نحوی در آن waiting ایجاد کنید، که از جمله این روش ها ShowDialog و یا Application.Run است، اما با ایجاد waiting عملا Thread متوقف شده است (چون در غیر این صورت Thread به اتمام رسیده و فرم بسته می شود) بنابراین کلیه عملیات مورد نظرتان را باید قبل از ایجاد waiting انجام دهید
این کار دقیقا مثل برنامه نویسی کلاس اصلی برنامه (Program.cs) است، شما بعد از Application.Run چیزی اضافه نمی کنید، شروع برنامه برای windows form معمولا با اجرای form اصلی است. در اینجا هم شروع برنامه در Thread 2 با نمایش فرم جدید است، بنابراین باید عملیات به قبل از نمایش فرم جدید و یا درون فرم جدید انتقال داده شود

sajadjamalian
شنبه 25 دی 1389, 15:22 عصر
سلام دوست عزیز:
با توجه به فرمایشات شما من فرم دومم رو بیرون ترد نمایش دادم ولی وقتی که برنامه میخواد کنترلی به این فرمم اضافه کنه ایراد زیر رو میگیره:
ممنون میشم توضیح بدی باید چیکار کنم که چنین ایرادی نگیره:

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

prankster
شنبه 25 دی 1389, 15:48 عصر
من اینطور فرض می کنم اگر غیر از این بود بگویید:
نمایش فرم ها درون Thread اصلی انجام می شود، انجام عملیات از درون Thread های دیگر انجام می شود، که این عملیات ممکن است با فرم ها کنش داشته باشد (مثل اضافه کردن کنترل)

در این گونه موارد از آنجایی که Handle فرم توسط Thread اصلی ایجاد شده است دسترسی به آن از طریق Thread های دیگر امکان پذیر نیست! از طریق متد Invoke از فرم عملیات را از Thread دوم به Thread اصلی بر می گردانید. به عنوان ورودی به متد Invoke یک delegate از متدی که عملیات در آن انجام می شود ارسال کنید

sajadjamalian
شنبه 25 دی 1389, 15:55 عصر
سلام دوست عزیز:
آره درسته منظورم همین بود،
میشه لطف کنید یه نمونه کد از توضیحاتی که دادید برام بذارید. ممنون.

hossin.esm
شنبه 25 دی 1389, 17:09 عصر
من یک نمونه ایجاد کردم و ضمیمه کردم

esmaeily-hosein
شنبه 25 دی 1389, 18:10 عصر
بعد از اینکه فرم را ShowDialog میکنی خط های بعدی برنامه خوب مسلماْ اجرا نحواهند گشت.
میتوانی متدی به نام InitControls بنویسی و قبل از showDialog آنرا فراخوانی کنی.

در غیر این صورت میتوانی با استفاده از signal به thread ی که فرم را ایجاد کرده است message فرستاده و به آن کنترل های خود را اضافه کنی (Not Recommend )


ولی معمولا تراکنش های سنگین در thread ی دیگر انجام میشوند و در صورت لزوم اگر لازم بود تغییری در ui صورت گیرد با استفاده از invoke آنرا در main thread اجرا میکنند.