PDA

View Full Version : تابع های تو در تو در background worker



sajadsobh
پنج شنبه 22 بهمن 1394, 09:20 صبح
سلام دوستان و اساتید محترم. خسته نباشید.
من یه برنامه تحت ویندوز نوشتم که باید یه سری اطلاعات رو از لوکال به سمت هاست بفرستم که این ارسال اطلاعات رو توی تابع Send نوشتم حالا توی همین ثبت دیتا نیاز دارم که یه عکس هم آپلود کنم و آدرسش رو برگردونم و این کار رو توی تابع UploadImage انجام دادم که این تابع توی تابع Send فراخونی میشه. حالا واسه اینکه کاربر فکر نکنه برنامه هنگ کرده اومدم یه عکس Gif و یه متن با تکست "در حال ارسال اطلاعات" قرار دادم که وقتی شروع به ارسال و آپلود شد اون Gif نمایش داده بشه.
138977
و اینکار رو هم با یه backgroundworker انجام دادم به این شکل:

private void btn_save_Click(object sender, EventArgs e)

{
lbl_waiting.Visible = true;
pic_waiting.Visible = true;
foreach (Control x in this.Controls)
{
if (!(x is PictureBox))
x.Enabled = false;
}
if (!backgroundWorker1.IsBusy)
backgroundWorker1.RunWorkerAsync();
}


private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Send();
}



private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error == null)
{
if (flag)
{
lbl_waiting.Visible = false;
pic_waiting.Visible = false;
MessageBox.Show(this, "عملیات ثبت با موفقیت انجام شد.", "تکمیل عملیات!", MessageBoxButtons.OK,
MessageBoxIcon.None, MessageBoxDefaultButton.Button1,
MessageBoxOptions.RightAlign | MessageBoxOptions.RtlReading);
frm_addedit_Load(null, null);
}
}
}

public void Send()
{
UploadImage();
//Do Somthing for Save Data
}
حالا مشکل اینجاست وقتی که برنامه میره توی تابع UploadImage و داره عکس ارسال میکنه مثه اینکه هنگ میکنه و عکس Gif من ثابت می مونه. ولی بعد از انجام آپلود دوباره برمیگرده به حالت عادی. فکر میکنم مشکل از اینه که تابع تو در تو استفاده کردم باشه. چون اومدم به جای دستورات توی Send و همچنین UploadImage از Sleep استفاده کردم. بازم ایست میکنه. یعنی ربطی به دستوراتی که توی Send و Upload نوشتم نیست. چه راه حلی واسش هست؟! :افسرده:

ژیار رحیمی
جمعه 23 بهمن 1394, 12:17 عصر
سلام
قبل از هر چیزی شما لازم نیست با یه حلقه for تمام کنترل های روی فرم رو به حالت غیر فعال دراری.به جای آن دکمه ثبت رو به حالت غیر فعال در بیار بعد از ارسال مجدد دکمه ارسال رو فعال کن.
با فرض اینکه کدهای ارسال تصویر مشکلی نداره.کدهای شما مشکلی در ظاهر نداره انچه به نظر من چنین مشکلی رو بوجود میارد احتمالا backgroundWorker هست.شما بهتره به جای متد RunWorkerAsync() از RunWorker() استفاده کن ببین مشکلت حل میشه.شما همچنین میتونی lbl_waiting و pic_waiting رو در یک Thread دیگر run کنی

peikesms123
جمعه 23 بهمن 1394, 12:56 عصر
سلام
توی دات نت جدید این مشکل حل شده و شما میتونید از async , await استفاده کنید.

sajadsobh
شنبه 24 بهمن 1394, 10:14 صبح
سلام
قبل از هر چیزی شما لازم نیست با یه حلقه for تمام کنترل های روی فرم رو به حالت غیر فعال دراری.به جای آن دکمه ثبت رو به حالت غیر فعال در بیار بعد از ارسال مجدد دکمه ارسال رو فعال کن.
با فرض اینکه کدهای ارسال تصویر مشکلی نداره.کدهای شما مشکلی در ظاهر نداره انچه به نظر من چنین مشکلی رو بوجود میارد احتمالا backgroundWorker هست.شما بهتره به جای متد RunWorkerAsync() از RunWorker() استفاده کن ببین مشکلت حل میشه.شما همچنین میتونی lbl_waiting و pic_waiting رو در یک Thread دیگر run کنی

RunWorker() همچین متدی نداره که!:لبخندساده:

sajadsobh
شنبه 24 بهمن 1394, 10:25 صبح
سلام
توی دات نت جدید این مشکل حل شده و شما میتونید از async , await استفاده کنید.

میشه بیشتر توضیح بدین؟!

ژیار رحیمی
شنبه 24 بهمن 1394, 13:25 عصر
سلام عذر خواهی میکنم با یه چیز دیگه اشتباهی گرفته شد.درسته Backgroundworker متدی با این نام نداره.اگر ورژن Net. شما 4.5 به بالا باشه میتونی از await و async استفاده کرد.شما بهتره کار نمایش lbl_waiting و pic_waiting از Thread استفاده کرد.یا از Progressbar استفاده کنی که نمونه مثال در لینک زیر مطالعه نمایید
https://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx
https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).a spx

جهت آشنایی بیشتر با await و async
https://msdn.microsoft.com/en-us/library/hh191443.aspx

و اما مشکل برمیگرده به دستکاری عناصر UI در Thread غیر از Thread جاری ،Backgroundworker یک Thread هست که در پس زمینه در حال اجرا میباشد.در Backgroundworker شما lbl_waiting و pic_waiting که در Thread اصلی هست رو دستکاری میکنی بهتر کد تابع backgroundWorker1_RunWorkerCompleted به صورت زیر اصلاح کنی

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error == null)
{
if (flag)
{
Invoke((MethodInvoker)delegate
{
lbl_waiting.Visible = false;
pic_waiting.Visible = false;
MessageBox.Show(this, "عملیات ثبت با موفقیت انجام شد.", "تکمیل عملیات!", MessageBoxButtons.OK,
MessageBoxIcon.None, MessageBoxDefaultButton.Button1,
MessageBoxOptions.RightAlign | MessageBoxOptions.RtlReading);
frm_addedit_Load(null, null);
});
}
}
}