PDA

View Full Version : ایجاد قابلیت Pause و Resume در برنامه C#



tanha70
دوشنبه 14 مهر 1393, 13:08 عصر
سلام

واسه یه حلقه While میخواام این ویژگی رو ایجاد کنم.


مثلا اگر دکمه P فشار داده بشه حلقه Pause بشه و اگر دکمه R فشار داده بشه برنامه Resume بشه از همون نقطه ای که Pause شده.


من خودم با C#‎‎‎ آشنایی دارم و بقیه برنامه رو هم خودم نوشتم. لطفا بفرمایید این قسمتش رو به چه صورت میخواین انجام بدین. همچنین نمونه کدی پیوست کردم.

پیوست:
124269

hamid_hr
دوشنبه 14 مهر 1393, 13:42 عصر
اگه با ترد کار کنی میتونی puse , resume رو پیاده کنی

elec60
دوشنبه 14 مهر 1393, 13:48 عصر
سلام

واسه یه حلقه While میخواام این ویژگی رو ایجاد کنم.


مثلا اگر دکمه P فشار داده بشه حلقه Pause بشه و اگر دکمه R فشار داده بشه برنامه Resume بشه از همون نقطه ای که Pause شده.


من خودم با C#‎‎‎‎‎‎‎‎‎‎ آشنایی دارم و بقیه برنامه رو هم خودم نوشتم. لطفا بفرمایید این قسمتش رو به چه صورت میخواین انجام بدین. همچنین نمونه کدی پیوست کردم.

پیوست:
124269


بدون برنامه نويسي آسنكرون فكر نميكنم بشه اين كار رو انجام داد. حلقه while بايد داخل يه Thread اجرا بشه و داخل حلقه دو تا متغيير بزاري براي چك كردن P و R.

اگه P زده شد متغيير بولين P ترو بشه و متغيير R فالز و اكه R زده شد متغيير R ترو بشه و P فالز بشه.

در حالت P بايد داخل حلقه، ترد رو تا بينهايت Sleep كني كه با پاس دادن 0 به متد Sleep اين كار انجام ميشه و در حالت بعدي Thread رو Resume كني.

چك كردن حالت P و R رو بهتره داخل بخشي از while بزاري كه حجم محاسباتش زياده تا به محض Pause كردن عمل كنه و وقفه ايجاد نشه.

مثلا اگه حلقه for خفني داري بهتره بزاريش داخل for


البته كد ننوشتم نميدونم جواب ميده يا نه. تست كن ببين چي ميشه

tanha70
دوشنبه 14 مهر 1393, 18:59 عصر
من با استفاده از thread این کار رو انجام دادم ولی الان یه مشکلی هست.
تابعی که هر بار اجرا میشه از تابع زیر هم استفاده میکنه


SendKeys.Send("^a");

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


SendKeys cannot run inside this application because the application is not handling Windows messages. Either change the application to handle messages, or use the SendKeys.SendWait method.

مشکل این قسمتش رو نمیدونم چطور باید رفع کنم...

plus
دوشنبه 14 مهر 1393, 20:01 عصر
اول بگم که استفاده از SendKeys کلا توصیه نمیشه.
علت خطا هم این هست که شما Thread جدیدی ساختین و کد SendKeys رو در اون اجرا میکنید.این Thread به اصطلاح Message Pump نداره و مثل Thread اصلی برنامه تون نیست.
راهی میشه پیدا کرد که از Thread دیگه استفاده نکنید. ولی خوب، راهی که الان به ذهنم میرسه اینه که با استفاده از متد BeginInvoke مربوط به فرم (البته از پروژتون WinForms هست)، کد مورد نظر رو در اون اجرا کنید...

void WorkerThread() {
while (condition) {
this.BeginInvoke((MethodInfo) delegate {
SendKeys.Send("^a");
});
}
}

در این حالت حلقه در Thread دیگه اجرا میشه ولی متد Send در Thread مربوط به UI اجرا میشه.

مهرداد صفا
دوشنبه 14 مهر 1393, 20:10 عصر
سلام.
بدون thread هم میتونید پیاده کنید. به طوری که از دو حلقه استفاده کنید. از این الگو استفاده کنید:



public bool running=true;
public bool paused =false;

void loop()
{
while(running)
{
Application.DoEvents();
while(paused)
{
Application.DoEvents();
//این حلقه فقط برای توقف استفاده میشه.
}
//در صورت pause نبودن حلقه بالا متوقف و در این قسمت اعمال اصلی اجرا میشن
}

}

void KeyDown(...
{
if(e.KeyCode=Keys.P)
paused=true;
if(e.KeyCode=Keys.R)
paused=false;
}


اون خطا هم احتمالا به دلیل اینه که برنامه مقصد not responding شده (کمی هنگیده) و پیغام ها رو پردازش نمی کنه. اگر برنامه مقصد که کلید رو بهش ارسال می کنید رو خودتون نوشتید، با اضافه کردن:

Application.DoEvents();
به داخل حلقه، اجازه پردازش سایر پیغام های ویندوز رو به برنامه بدید.

tanha70
جمعه 17 بهمن 1393, 17:51 عصر
ایده تابع loop خیلی خوب بود ولی قسمتی که با تابع Keydown هست مشکل داره.
اگر من مثلا حتی از کد زیر هم استفاده کنم


private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.P)
paused = true;
if (e.KeyCode == Keys.R)
paused = false;
}


بازم یه مشکلی دارم که اونم اینه که دکمه های p و r رو باید در محیط فرمم وارد کنم و اگر برنامه minimize شده باشه دیگه کار نمیکنه.
این مورد هم ممنون میشم راهنمایی بفرمایید.