PetekDincos
چهارشنبه 01 تیر 1390, 13:19 عصر
با سلام
من برای پر کردن کنترلهای WPF مثل DataGrid,ListView,... که تو لود فرمم می خوام پر بشند و از یک ORM مثل EF کوئری می گیرم و اون رو به این کنترلها بایند می کنم و چون ممکنه هزینه کوئری و بایند من بالا باشه و فرم به حالت فریز بره می خوام از BackgroundWorker استفاده کنم مثلا برای پر کردن یک ListView با یک جدول از دیتابیسم به صورت زیر از Backgroundworker استفاده می کنم
public partial class MainWindow : Window
{
private BackgroundWorker _bw;
public MainWindow()
{
InitializeComponent();
_bw = new BackgroundWorker()
{
WorkerReportsProgress=true,
WorkerSupportsCancellation=true
};
_bw.DoWork += bw_DoWork;
_bw.RunWorkerCompleted += bw_RunWorkerComplete;
_bw.ProgressChanged += bw_ProgressChanged;
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 100; i ++)
{
if (_bw.CancellationPending) { e.Cancel = true; return; }
_bw.ReportProgress(i);
Thread.Sleep(10);
}
e.Result = "RunWorkerComplete";
}
private void bw_RunWorkerComplete(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
if (_bw.IsBusy)
_bw.CancelAsync();
}
else if (e.Error != null)
{
if (_bw.IsBusy)
_bw.CancelAsync();
MessageBox.Show(e.Error.ToString());
}
else
{
MainListView.ItemsSource = FillListView();
}
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// MainListView.ItemsSource =(List<MyClass>) e.UserState;
Progress1.Value = e.ProgressPercentage;
}
private List<MyClass> FillListView()
{
List<MyClass> MyList=new List<MyClass>();
for (int i = 1; i < 10000000; i++)
MyList.Add(new MyClass(){Name="Name "+i,Family="Family "+i,Age=i});
return MyList;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
_bw.RunWorkerAsync();
}
}
public class MyClass
{
public string Name { get; set; }
public string Family { get; set; }
public int Age { get; set; }
}
که در اینجا MyClass مثلا جدول من در دیتابیسمه و متد FillListView یک کوئری از ORM است و معلوم نیست این کوئری تعداد رکوردهای برگشتیش چندتا باشه و من در متد DoWork بگروندم در یک حلقه از 1 تا 100 و با Sleep 10 می خوام پراپرتی Value کنترل ProgressBar توی فرم رو مقداردهی کنم تا در رویداد ProgressChanged این کار انجام بشه و چون کوئری برگشتی از دیتابیسم هزینش بالاست با این نمایشی که ProgressBar داره هم خوانی نداره می خواستم بدونم وقتی از یک ORM مثل EF یک کوئری گرفته می شه رویدادهای BackgroundWorker رو چطور بنویسیم که با پر شدن ProressBar هم خوانی داشته با شه
و اگه سوالم زیاد در هم برهم بود ببخشید با تشکر
من برای پر کردن کنترلهای WPF مثل DataGrid,ListView,... که تو لود فرمم می خوام پر بشند و از یک ORM مثل EF کوئری می گیرم و اون رو به این کنترلها بایند می کنم و چون ممکنه هزینه کوئری و بایند من بالا باشه و فرم به حالت فریز بره می خوام از BackgroundWorker استفاده کنم مثلا برای پر کردن یک ListView با یک جدول از دیتابیسم به صورت زیر از Backgroundworker استفاده می کنم
public partial class MainWindow : Window
{
private BackgroundWorker _bw;
public MainWindow()
{
InitializeComponent();
_bw = new BackgroundWorker()
{
WorkerReportsProgress=true,
WorkerSupportsCancellation=true
};
_bw.DoWork += bw_DoWork;
_bw.RunWorkerCompleted += bw_RunWorkerComplete;
_bw.ProgressChanged += bw_ProgressChanged;
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 100; i ++)
{
if (_bw.CancellationPending) { e.Cancel = true; return; }
_bw.ReportProgress(i);
Thread.Sleep(10);
}
e.Result = "RunWorkerComplete";
}
private void bw_RunWorkerComplete(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
if (_bw.IsBusy)
_bw.CancelAsync();
}
else if (e.Error != null)
{
if (_bw.IsBusy)
_bw.CancelAsync();
MessageBox.Show(e.Error.ToString());
}
else
{
MainListView.ItemsSource = FillListView();
}
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// MainListView.ItemsSource =(List<MyClass>) e.UserState;
Progress1.Value = e.ProgressPercentage;
}
private List<MyClass> FillListView()
{
List<MyClass> MyList=new List<MyClass>();
for (int i = 1; i < 10000000; i++)
MyList.Add(new MyClass(){Name="Name "+i,Family="Family "+i,Age=i});
return MyList;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
_bw.RunWorkerAsync();
}
}
public class MyClass
{
public string Name { get; set; }
public string Family { get; set; }
public int Age { get; set; }
}
که در اینجا MyClass مثلا جدول من در دیتابیسمه و متد FillListView یک کوئری از ORM است و معلوم نیست این کوئری تعداد رکوردهای برگشتیش چندتا باشه و من در متد DoWork بگروندم در یک حلقه از 1 تا 100 و با Sleep 10 می خوام پراپرتی Value کنترل ProgressBar توی فرم رو مقداردهی کنم تا در رویداد ProgressChanged این کار انجام بشه و چون کوئری برگشتی از دیتابیسم هزینش بالاست با این نمایشی که ProgressBar داره هم خوانی نداره می خواستم بدونم وقتی از یک ORM مثل EF یک کوئری گرفته می شه رویدادهای BackgroundWorker رو چطور بنویسیم که با پر شدن ProressBar هم خوانی داشته با شه
و اگه سوالم زیاد در هم برهم بود ببخشید با تشکر