Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
保持C#应用程序打开并检查数据库_C#_Sql Server_Infinite Loop - Fatal编程技术网

保持C#应用程序打开并检查数据库

保持C#应用程序打开并检查数据库,c#,sql-server,infinite-loop,C#,Sql Server,Infinite Loop,我有这个应用程序。与一个数据库连接并向android设备发送通知。我想保持此应用程序始终打开,并检查数据库中的新记录。我唯一的想法是放入一个无限循环,如while(true),但我在connection.Open()行中有警告关于内存,程序正在停止 namespace AndroidParse { class Program { static void Main(string[] args) { //SqlDataReader reader; S

我有这个应用程序。与一个数据库连接并向android设备发送通知。我想保持此应用程序始终打开,并检查数据库中的新记录。我唯一的想法是放入一个无限循环,如while(true),但我在connection.Open()行中有警告关于内存,程序正在停止

namespace AndroidParse
{
class Program
{

    static void Main(string[] args)
    {
        //SqlDataReader reader;
        SqlConnection conn = new SqlConnection();

        string queryString = "SELECT TOP 1 device_id FROM Temp ORDER BY ID_Requests DESC";
        string connectionString = "XXXX";

        while (true)
        {

            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                SqlCommand command = new SqlCommand(queryString, connection);

                connection.Open();

                SqlDataReader reader = command.ExecuteReader();
                try
                {
                    while (reader.Read())
                    {



                        Console.WriteLine(reader[0]);
                        bool isPushMessageSend = false;

                        string postString = "";
                        string urlpath = "https://api.parse.com/1/push";
                        var httpWebRequest = (HttpWebRequest)WebRequest.Create(urlpath);

                        postString = "{\"data\": { \"alert\": \"Finally is working\" },\"where\": { \"device_id\": \"" + reader[0] + "\" }}";
                        httpWebRequest.ContentType = "application/json";
                        httpWebRequest.ContentLength = postString.Length;
                        httpWebRequest.Headers.Add("X-Parse-Application-Id", "XXXX");
                        httpWebRequest.Headers.Add("X-Parse-REST-API-KEY", "XXXX");
                        httpWebRequest.Method = "POST";

                        StreamWriter requestWriter = new StreamWriter(httpWebRequest.GetRequestStream());
                        requestWriter.Write(postString);
                        requestWriter.Close();
                        var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();


                        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                        {
                            var responseText = streamReader.ReadToEnd();
                            JObject jObjRes = JObject.Parse(responseText);
                            if (Convert.ToString(jObjRes).IndexOf("true") != -1)
                            {
                                isPushMessageSend = true;
                            }
                        }
                        //--------------------------------------------------
                        SqlConnection sqlConnection1 = new SqlConnection(connectionString);
                        SqlCommand cmd = new SqlCommand();
                        SqlDataReader reader1;

                        cmd.CommandText = "delete from Temp where ID_Requests in (select top 1 ID_Requests from Temp order by ID_Requests desc)";

                        cmd.Connection = sqlConnection1;

                        sqlConnection1.Open();

                        reader1 = cmd.ExecuteReader();
                        // Data is accessible through the DataReader object here.

                        sqlConnection1.Close();
                        //--------------------------------------------------
                        Console.ReadLine();
                    }
                }
                finally
                {
                    reader.Close();
                }
                connection.Close();

            }
        }

    }

    private static void println()
    {
        throw new NotImplementedException();
    }
}

}

使用Denis Reznik建议的
SqlDependency
对象是一个很好的解决方案。 需要记住的几件事:

  • SqlDependency
    要求SQL Server Service Broker服务在SQL Server上运行(此处有更多详细信息:)

  • 可以在
    SqlCommand
    中使用的查询基本上是在服务器上连续执行的。。。因此,查询的功能有一些限制(例如,没有聚合)。更多详情请参见Smudge202的SO答案:

  • 我发现使用
    SqlDependency
    来简单地通知更改,然后通过调用数据访问方法等来执行更改。。。比尝试实际使用查询检索数据更容易。因此,在您的示例中,您可能希望让
    SqlDependency
    通知有更改,然后创建一个单独的数据访问方法/sp/etc。。。检索设备id等详细信息

  • 这是一个基于上面代码的示例。。。这可能需要一些调整。祝你好运

    namespace AndroidParse
    {
        public class DbMonitor
        {
            private readonly string _connectionString = ConfigurationManager.ConnectionStrings["XXXXX"].ConnectionString;
            private SqlDependency _dependency;
            private SqlConnection _conn;
            private SqlCommand _command;
            public void MonitorDatabase()
            {
                SqlDependency.Start(_connectionString);
    
                // Open DB Connection
                using (_conn = new SqlConnection(_connectionString))
                {
                    // Setup SQL Command
                    using (_command = new SqlCommand("SELECT TOP 1 device_id FROM Temp ORDER BY ID_Requests DESC", _conn))
                    {
                        // Create a dependency and associate it with the SqlCommand. *** MAGIC ****
                        _dependency = new SqlDependency(_command);
    
                        // Subscribe to the SqlDependency event.
                        _dependency.OnChange += HandleDatabaseChange;
    
                        // Execute 
                        _command.Connection.Open();
                        _command.ExecuteReader();
                    }
                }
            }
    
            public void Stop()
            {
                SqlDependency.Stop(_connectionString);
            }
    
            private void HandleDatabaseChange(object sender, SqlNotificationEventArgs e)
            {
                if (e.Info == SqlNotificationInfo.Invalid)
                {
                    Console.WriteLine("The above notification query is not valid.");
                }
                else
                {
                    Console.WriteLine("Database Changed based on query");
                    Console.WriteLine("------------------------------------");
                    Console.WriteLine("Event Details:");
                    Console.WriteLine("Notification Info: " + e.Info);
                    Console.WriteLine("Notification source: " + e.Source);
                    Console.WriteLine("Notification type: " + e.Type);
                }
    
                //PushMessage logic here
                bool isPushMessageSend = false;
    
                string postString = "";
                string urlpath = "https://api.parse.com/1/push";
                var httpWebRequest = (HttpWebRequest)WebRequest.Create(urlpath);
    
                // Use Query to get device_id? 
    
                postString = "{\"data\": { \"alert\": \"Finally is working\" },\"where\": { \"device_id\": \"" + "deviceID" + "\" }}";
                httpWebRequest.ContentType = "application/json";
                httpWebRequest.ContentLength = postString.Length;
                httpWebRequest.Headers.Add("X-Parse-Application-Id", "XXXX");
                httpWebRequest.Headers.Add("X-Parse-REST-API-KEY", "XXXX");
                httpWebRequest.Method = "POST";
    
                StreamWriter requestWriter = new StreamWriter(httpWebRequest.GetRequestStream());
                requestWriter.Write(postString);
                requestWriter.Close();
                var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
    
    
                using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                {
                    var responseText = streamReader.ReadToEnd();
                    JObject jObjRes = JObject.Parse(responseText);
                    if (Convert.ToString(jObjRes).IndexOf("true") != -1)
                    {
                        isPushMessageSend = true;
                    }
                }
    
                // Resume Monitoring... Requires setting up a new connection, etc.. Reuse existing connection? Tried.
                MonitorDatabase();
            }
        }
    }
    
    class Program
    {
    
        static void Main(string[] args)
        {
            try
            {
                // Start the cheese monitor
                DbMonitor dbMonitor = new DbMonitor();
                dbMonitor.MonitorDatabase();
    
                Console.WriteLine("Monitoring....Press any key to stop.");
                Console.Read();
    
                dbMonitor.Stop();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
            finally
            {
                SqlDependency.Stop(ConfigurationManager.ConnectionStrings["XXXXX"].ConnectionString);
            }
        }
    }
    

    计时器可能更合适。您也可以将其包装到windows服务中。如果您具有对数据库的写入权限,只需在更新或插入时设置触发器,并让它执行此脚本即可。否则,是的,计时器可能是最好的。计时器成就了我的一天。谢谢大家。请记住,如果您使用的是计时器(而不是DB触发器),如果在timer.tick事件中进行了多个更新,那么您将只对最近的一个进行操作,因为您只选择了“前1个”