مشکل با progress bar
1 پاسخ
سلام وقتتون بخیر
در ویندوز فرم ، ProgressBar دارای دو پراپرتی با نام های Minimum و Maximum هست. شما بایستی فرایندی که قصد انجامش رو دارین ، در قالب یک عدد شروع و پایان برای ProgressBar مشخص کنین و در حلقه ی خودتون ، با هر Iteration یی که صورت میگیره به مقدار پراپرتی Value مربوط به ProgressBar یک واحد اضافه کنین.
این مثال رو در نظر بگیرید:
شما قصد دارید تا 10 فایل رو بخونید و محتواش رو پردازش کنین . پس ما اینجا از 0 تا 10 میشه بازه ی ما برای Minimum و Maximum که بروی ProgressBar سِت میکنیم .
progressBar1.Minimum = 0;
progressBar1.Maximum = 10;
progressBar1.Value = 0;
حالا ما یک حلقه داریم که میخوایم در هربار که عملیات رو انجام میده ، و یک فایل رو پردازش میکنه ، یک واحد ProgressBar رو به جلو ببریم:
for (var file in files)
{
// Read file
// Process the file
progressBar1.Value++;
}
تا به اینجا عملیات اوکی هست ، فقط مشکل اینجاست ، اگر این عملیات بر روی Main Thread انجام بشه ، عملا فرم ما تا پایان انجام عملیات فریز میشه و در آخر ، یک دفعه ProgressBar پر میشه و ...
برای اینکه این مورد حل بشه ، باید کدی که عملیات رو انجام میده در داخل یک Thread مجزا اجرا باشه تا خللی در عملکرد MainThread ایجاد نکنه .
برای اینکار هم میتونین از ابزار BackgroundWorker استفاده کنین ، همینطور از Task ها . مثلا از طریق Task ها به شکل زیر میتونین عمل کنید:
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 فرم ، به شکل زیر عمل میکنیم:
private async void Form1_Load(object sender, EventArgs e)
{
await Task.Run(PerformDummyWorkAsync);
}