[英]Keep C# app open and check the database
我有這個程序。 與一個數據庫連接並向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上運行(此處有更多詳細信息: https : //msdn.microsoft.com/zh-cn/library/ms172133 ( v=vs.110 ) .aspx )
可以在SqlCommand
中使用的查詢實際上是在服務器上連續執行的。因此,對於查詢可以執行的操作有一些限制(例如,沒有聚合)。 來自Smudge202的SO答案中的更多詳細信息: SqlDependency的局限性是什么
我發現使用SqlDependency
來簡單地通知更改,然后通過調用數據訪問方法等對它進行操作比嘗試實際使用查詢檢索數據要容易。 因此,在您的示例中,您可能想讓SqlDependency
通知有更改,然后創建一個單獨的數據訪問方法/ sp / etc ...以檢索諸如device_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);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.