Добавить асинхронный вывод статистки по данным в БД которая будет обновляться по таймеру.
Транзакции / подсказка к 2 задачке
Добавляем на форму панельку куда будем выводить статистику, и делаем на ней лейбл lblStatistics чтобы просто в него писать данные
Добавляем timer на форму
и ставим ему свойства какие-то такие
Enabled – это чтобы таймер запустился. А интервал — это как часто мы будем опрашивать базу.
Теперь тыкаем два раза на таймер.
Добавим теперь метод для расчета статистики. Делаем его по аналогии с методами для генерации. То есть он должен принимать на вход конекшен.
// метод для генерации статистики
private void GetStatistics(SqlConnection connection)
{
using (connection)
{
connection.Open();
}
}
// метод вызывающийся каждую итерацию таймера, не забываем добавить async
private async void timer1_Tick(object sender, EventArgs e)
{
var connection = GetConnection();
await Task.Run(() =>
{
GetStatistics(connection);
});
}
Теперь мне надо сделать чтобы метод собственно эту статистику возвращал. Так как статистика может содержать кучу данных. То создадим под нее отдельный класс.
я хочу, чтобы мой метод который GetStatistics, возвращал экземпляр этого класса. А реакция на тик таймера, которая запускает этот метод асинхронно получала этот экземпляр и выводила его на форму. К счастью тут почти не надо править код. Достаточно просто написать код — вот так
// тут меняем void на Statistics
private Statistics GetStatistics(SqlConnection connection)
{
var statistics = new Statistics();
using (connection)
{
connection.Open();
}
return statistics;
}
private async void timer1_Tick(object sender, EventArgs e)
{
var connection = GetConnection();
// тут сохраняем результат асинхронного вызова в переменную
Statistics statistics = await Task.Run(() =>
{
// ну и тут return добавляем
return GetStatistics(connection);
});
}
ну теперь можно добавить немного логики для расчёта значений. Например, посчитаю количество кошек, а также отдельные значения по породам
private Statistics GetStatistics(SqlConnection connection)
{
var statistics = new Statistics();
using (connection)
{
connection.Open();
// запрашиваем количество кошек
var command = new SqlCommand("SELECT count(*) FROM cats", connection);
statistics.catsCount = (int)command.ExecuteScalar(); // сохраняем в статистку
// запрашиваем количество кошек по породам
command = new SqlCommand("SELECT breed, count(*) as count FROM cats GROUP BY breed", connection);
// создаем экземпляр словарика
statistics.catsCountsByBreed = new Dictionary<string, int>();
// ну и проходим по строкам которые вернул запрос
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
if (!reader.IsDBNull("breed")) // проверяем что порода не пустая
{
// добавляем в словарик запись, в качестве ключа название породы, в качестве значение количество
statistics.catsCountsByBreed[reader.GetString("breed")] = reader.GetInt32("count");
}
}
}
}
return statistics;
}
private async void timer1_Tick(object sender, EventArgs e)
{
var connection = GetConnection();
var statistics = await Task.Run(() =>
{
return GetStatistics(connection);
});
// тут хитро формируем строку со списком пород
var breedsInfo = String.Join(
"\n",
statistics.catsCountsByBreed
.Select(x => x.Key)
.OrderBy(x => x)
.Select(x => $" - {x}: {statistics.catsCountsByBreed[x]}")
);
// и теперь выводим на форму
lblStatistics.Text = $"Кошек и котов: {statistics.catsCount}\n"
+ $"{breedsInfo}";
}
запускаем и проверяем:
красота! =)