تا 90% تخفیف روی همه دوره‌ها + گارانتی بازگشت وجه + مدرک معتبر + منتورینگ استاد
پایان تخفیف تا:
مشاهده دوره‌ها
0

مشکل با progress bar

سلام دوستان من یه ویندوز فرم توی ویژوال استودیو ایجاد کردم و یه پروگرس بار توش گذاشتم حالا یه حلقه for دارم که کارش تغییر دیتای یه متغیر از نوع استرینگ هست زمانی که کلیک می کنم و حلقه for اجرا میشه تقریبا 5 ثانیه طول میکشه تا تبدیل به طور کامل انجام بشه و این 5 ثانیه بسته به خجم دیتا بعضا کم و زیاد میشه مثلا شاید بشه 2 ثانیه حالا من می خوام پروگرس بار رو با این مچ کنم مشکل من اینه که حلقه for ک اجرا میشه فرم هنگ می کنه و بعد اینکه پردازش حلقه for به پایان رسید یه دفعه پروگرس بار میشه 100 درصد یه راهنمایی می کنید این پروگرس بار به صورت نرم اجرا بشه تا برسه به صد؟
پرسیده شده در 1402/04/05 توسط

1 پاسخ

1

سلام وقتتون بخیر

در ویندوز فرم ، ProgressBar دارای دو پراپرتی با نام های Minimum و Maximum هست. شما بایستی فرایندی که قصد انجامش رو دارین ، در قالب یک عدد شروع و پایان برای ProgressBar مشخص کنین و در حلقه ی خودتون ، با هر Iteration یی که صورت میگیره به مقدار پراپرتی Value مربوط به ProgressBar یک واحد اضافه کنین. 

این مثال رو در نظر بگیرید:

شما قصد دارید تا 10 فایل رو بخونید و محتواش رو پردازش کنین . پس ما اینجا از 0 تا 10 میشه بازه ی ما برای Minimum و Maximum که بروی ProgressBar سِت میکنیم .

Code
progressBar1.Minimum = 0;
progressBar1.Maximum = 10;
progressBar1.Value = 0;

حالا ما یک حلقه داریم که میخوایم در هربار که عملیات رو انجام میده ، و یک فایل رو پردازش میکنه ، یک واحد ProgressBar رو به جلو ببریم:

Code
for (var file in files)
{
// Read file
 // Process the file
progressBar1.Value++;
}

تا به اینجا عملیات اوکی هست ، فقط مشکل اینجاست ، اگر این عملیات بر روی Main Thread انجام بشه ، عملا فرم ما تا پایان انجام عملیات فریز میشه و در آخر ، یک دفعه ProgressBar پر میشه و ...

برای اینکه این مورد حل بشه ، باید کدی که عملیات رو انجام میده در داخل یک Thread مجزا اجرا باشه تا خللی در عملکرد MainThread ایجاد نکنه .

برای اینکار هم میتونین از ابزار BackgroundWorker استفاده کنین ، همینطور از Task ها . مثلا از طریق Task ها به شکل زیر میتونین عمل کنید:

Code
Task PerformDummyWorkAsync()
{
foreach (var i in Enumerable.Range(0,10))
{
    Thread.Sleep(500);
    this.Invoke(new Action(() =>
        {
            progressBar1.Value++;
          }));
}
return Task.CompletedTask;
}

در کد بالا ، یک عملیاتی انجام میشه که هر Iteration حدود نیم ثانیه طول میکشه ، بعد از اون با استفاده از متد Invoke که داخل Form در دسترس هست ، یک Action اجرا میشه که باعث میشه Action مربوطه در Main Thread اجرا بشه .

برای اجرای این متد ، مثلا در داخل ایونت کلیک یک button یا Load فرم ، به شکل زیر عمل میکنیم:

Code
private async void Form1_Load(object sender, EventArgs e)
{
 await Task.Run(PerformDummyWorkAsync);
}
پاسخ در 1402/04/05 توسط

پاسخ شما