Реализация обработчика событий 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);
            }
        }
    }
}
Другие вопросы по тегам