У меня многоуровневое приложение. Уровень GUI, нажимая кнопку, вызывает мой бизнес-уровень, который вызывает метод со слоя данных, чтобы получить доступ к базе данных и привести список пользователей.
Как вызвать методы уровня данных без блокировки GUI с пользователем.
Методы уровня данных должны получать параметры и возвращать параметры.
Например: Список всех активных пользователей в базе данных.
IEnumerable <users> lstUsr = db.ListUsers(bool isActive);
Вместо того, чтобы нести расходы на управление потоками, пусть параллельная библиотека задач сделает это за вас:
protected void SomeButton_OnClick(Object sender, EventArgs e)
{
// A new task is not necessarily a new thread!
Task.Factory.StartNew(() => PopulateSomeControl());
}
private async Task RequestDataAndPopulateTheControl()
{
Statusbar.Text = "Loading from DB...";
// this blocks only this method, not the UI thread.
var data = await RequestData();
// data is now available
foreach(var whatever in data.ToList())
SomeControl.Items.Add(whatever);
Statusbar.Text = "Ready.";
}
private async Task<DataTable> RequestData()
{
var db = new YourDbContext();
return db.SomeDbSet().ToDataTable();
}
Метод RequestDataAndPopulateTheControl()
теперь становится читаемым объединением вашего асинхронного потока запроса на данные, а также обратного вызова для использования данных. Поток пользовательского интерфейса не заблокирован.
Как указывает ваш тег, прокрутите поток! Вам просто нужно помнить о необходимости Dispatcher.BeginInvoke, чтобы поместить элемент пользовательского интерфейса обратно в поток пользовательского интерфейса, когда вы закончите.
new Thread(() =>
{
IEnumerable<User> lstUsr = db.ListUsers(isActive);
Distpatcher.BeginInvoke(() =>
{
myUiVariable = lstUsr;
}
}
Если у вас есть доступ к асинхронному уровню доступа к данным и в.NET 4. 0+, вы можете воспользоваться async/await
myUiVariable = await db.ListUsersAsync(isActive);