Реализация обработчика событий C#
c#
приложение пишет на MS SQL
Таблица БД в несколько раз. записи этой таблицы должны быть прочитаны и обработаны другим c#
приложение.
На данный момент я реализовал I Threading timer, который просматривает (каждые 2 секунды), есть ли в таблице строки и обрабатывает ли данные:
System.Threading.Timer checkTimer;
checkTimer = new System.Threading.Timer(Callback, null, 2000, 500);
private void InitSQLCon()
{
Con = new SqlConnection(ConectionString);
Con.Open();
}
private void Callback(Object state)
{
string queryString = "Select [Wi_Customer ID],[Wi_License_plate_ID] from " + Properties.Settings.Default.Table1 + " where Wi_Car_Rfid='" + s + "'";
SqlCommand command = new SqlCommand(queryString, Con);
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
///...make neccessary operations
}
}
Моя проблема в том, что текущая реализация неэффективна. Проверка таблицы с помощью таймера занимает много ресурсов. Я хотел бы сделать это на основе событий. В идеале я хотел бы реализовать обработчик события add record to table1
событие. Если это возможно (поскольку я никогда не реализовывал обработчик событий), я был бы признателен за любые отзывы о том, как это можно сделать.
1 ответ
В SQL Server есть некоторые функции отслеживания изменений, наиболее заметными из которых являются SqlDependency
- однако, честно говоря, я думаю, что вам лучше взглянуть на отдельный механизм уведомления. Например, я большой поклонник redis pub/sub, потому что его нелепо просто настроить (черт, выделенный сервер pub-sub даже не нуждается в постоянстве, поэтому проблема с "bgsave"/"fork" делает Redis сложно на Windows не применяется, так что вы можете просто использовать Redis-сервер, доступный на Nuget). Затем ваш работник подписывается на именованный канал, а другие части системы передают сообщение на этот именованный канал при добавлении работы. Просто и эффективно. Для надежности вы также хотели бы периодически опрашивать вручную - но, вероятно, в более медленном опросе - возможно, каждые 30 секунд или что-то в этом роде.
Вот пример использования pub / sub с помощью redis через BookSleeve (вам также понадобится сервер redis, работающий на локальной машине):
using System;
using System.Text;
using BookSleeve;
static class Program
{
static void Main()
{
// IMPORTANT: the "pub" and "sub" can be on entirely separate machines,
// as long as they are talking to the same server. They are only shown
// together here for convenience
using (var sub = new RedisSubscriberConnection("localhost"))
using (var pub = new RedisConnection("localhost"))
{
sub.Open();
pub.Open();
sub.Subscribe("busytime", (queue,payload) =>
{
// you don't actually need the payload, probably
var received = Encoding.UTF8.GetString(payload);
Console.WriteLine("Work to do! Look busy!: " + received);
});
string line;
Console.WriteLine("Enter messages to send, or q to quit");
while((line = Console.ReadLine()) != null && line != "q")
{
pub.Publish("busytime", line);
}
}
}
}