ساخت یک Non-Freezing ساده در Windows Form

در این برنامه یاد می گیریم که چطور مشکل متوقف شدن و یا به اصطلاح "Freeze " شدن برنامه هایمان را برطرف کنیم. نویسنده با یک راهکار ساده ، این مشکل را برطرف می کند.

ساخت یک Non-Freezing  ساده در Windows Form

در این مقاله ، من یک window form ساده را طوری کدنویسی می کنم که در   UI  برنامه، به طور ناگهانی متوقف نشود و بدون مکث و یا به اصطلاح "Freeze" شدن به عملیات خودش ادامه بدهد.

این مثال ، می تواند در گرفتن اطلاعات (رکورد ها) از پایگاه داده و یا فراخوانی یک کار که به  زمان طولانی برای اجرا نیاز دارد، مورد استفاده قرار بگیرد.

ایجاد یک Windows Form

یک Windows Forms Application ساده در Visual Studio ایجاد کنید.

حالا یک رویداد Click  برای دکمه قرار بدهید و کد زیر را در آن وارد کنید.

private void button1_Click(object sender, EventArgs e)  
{  
for (var i = 0; i <= 1000000; i++)  
{  
label1.Text = @"Count : " + i;  
}  
}

برنامه را اجرا کنید و دکمه ی Start  را بزنید... با زدن دکمه ی Start  خواهید دید که برنامه متوقف می شود و به اصطلاح ، "Freeze" می شود. نگاهی به Task Manager خودتان بندازید تا ببینید که برنامه در حالت Not Responding قرار گرفته است.

چطور این مشکل را برطرف کنیم ؟

بیایید یک دکمه ی دیگر اضافه کنیم و برای رویدادclick آن مطابق شکل زیر کد نویسی کنیم :

//attributes used to refresh UI  
private readonly SynchronizationContext synchronizationContext;  
private DateTime previousTime = DateTime.Now;  
    
public Form1()  
{  
InitializeComponent();  
synchronizationContext = SynchronizationContext.Current; //context from UI thread  
}  

private async void button2_Click(object sender, EventArgs e)  
{  
button1.Enabled = false;  
button2.Enabled = false;  
var count = 0;  
    
await Task.Run(() =>  
{  
for (var i = 0; i <= 1000000; i++)  
{  
UpdateUI(i);  
count = i;  
}  
});  
label1.Text = @"Count : " + count;  
button1.Enabled = true;  
button1.Enabled = false;  
}  
    
public void UpdateUI(int value)  
{  
var timeNow = DateTime.Now;  
    
//Here we only refresh our UI each 50 ms  
if ((DateTime.Now - previousTime).Milliseconds <= 50) return;  
  
//Send the update to our UI thread  
synchronizationContext.Post(new SendOrPostCallback(o =>  
{  
label1.Text = @"Count : " + (int)o;  
}), value);  
  
previousTime = timeNow;  
} 

من کلمه ی "ASYNC " را در داخل بخش رویداد دکمه قرار دادم تا از بروز مشکل "freeze" در UI  جلوگیری کند. در رویداد دکمه به بخش "TASK " نگاه کنید ، این متد ، شمارشگر تعداد دفعات برنامه را می سازد. در درون این بخش ، متد UpdateUI وجود دارد که label  را هر 50 میلی ثانیه ، به روز رسانی می کند.

برنامه را  اجرا کنید و نتیجه ی آن را ببینید.

آموزش سی شارپ

فایل های ضمیمه
دانلود نسخه ی PDF این مطلب