I have a console app that monitors a database using SqlDependency. The app is to monitor the database table and send an email once a new record is added in the table.
Everything works fine, just that each time a new record is added the whole query is executed again and all the records in the table are returned. What I actually want is to return only the newly added record in the table.
Here is my code below:
SQLWatcher class:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TestApp
{
public enum SqlWatcherNotificationType
{
Blocking,
Threaded // Launch in another thread so SqlWatcher can immediately start monitoring again.
}
public class SqlWatcher : IDisposable
{
private string ConnectionString;
private SqlConnection Connection;
private SqlCommand Command;
private SqlDataAdapter Adapter;
private DataSet Result;
private SqlWatcherNotificationType NotificationType;
public SqlWatcher(string ConnectionString, SqlCommand Command, SqlWatcherNotificationType NotificationType)
{
this.NotificationType = NotificationType;
this.ConnectionString = ConnectionString;
SqlDependency.Start(this.ConnectionString);
this.Connection = new SqlConnection(this.ConnectionString);
this.Connection.Open();
this.Command = Command;
this.Command.Connection = this.Connection;
Adapter = new SqlDataAdapter(this.Command);
}
public void Start()
{
RegisterForChanges();
}
public void Stop()
{
SqlDependency.Stop(this.ConnectionString);
}
public delegate void SqlWatcherEventHandler(DataSet Result);
public event SqlWatcherEventHandler OnChange;
public DataSet DataSet
{
get { return Result; }
}
private void RegisterForChanges()
{
// Remove old dependency object
this.Command.Notification = null;
// Create new dependency object
SqlDependency dep = new SqlDependency(this.Command);
dep.OnChange += new OnChangeEventHandler(Handle_OnChange);
// Save data
Result = new DataSet();
Adapter.Fill(Result);
// Notify client of change to DataSet
switch (NotificationType)
{
case SqlWatcherNotificationType.Blocking:
OnChange(Result);
break;
case SqlWatcherNotificationType.Threaded:
ThreadPool.QueueUserWorkItem(ChangeEventWrapper, Result);
break;
}
}
public void ChangeEventWrapper(object state)
{
DataSet Result = (DataSet)state;
OnChange(Result);
}
private void Handle_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type != SqlNotificationType.Change)
throw new ApplicationException("Failed to create queue notification subscription!");
//Clean up the old notification
SqlDependency dep = (SqlDependency)sender;
dep.OnChange -= Handle_OnChange;
//Register for the new notification
RegisterForChanges();
}
public void Dispose()
{
Stop();
}
}
}
Implementation:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Linq;
using System.Data.SqlClient;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
namespace TestApp
{
class Program
{
private static SqlWatcher SqlQueueWatcher;
// string pin = string.Empty;
string siteURL = "http://docapp/sites/nlpc";
public string benefitCheck()
{
DataContext db = new DataContext("Data Source=;Initial Catalog=ServiceTest;User ID=;password = ;Integrated Security=true");
BenefitDocModel RSAName = new BenefitDocModel();
CustomerCareContextDataContext LandingDb = new CustomerCareContextDataContext(siteURL);
IEnumerable<BenefitDocModel> r = db.GetTable<BenefitDocModel>().ToList<BenefitDocModel>();
var query = r.ToList();
var rsa = from rr in query
select ( new { rr.PIN , rr.Document_Name, rr.Firstname, rr.Surname, rr.URL});
foreach (var rsapin in rsa)
{
Console.WriteLine(rsapin);
// sendEmail(rsapin.PIN);
}
/*pin = RSAName.PIN;
RSAsLibraryDocument test = new RSAsLibraryDocument();
BenefitDocModel RSAName1 = db.GetTable<BenefitDocModel>().FirstOrDefault(x => x.PIN == pin);
if (pin == RSAName1.PIN)
{
test.PIN = RSAName.PIN;
test.UserID = RSAName.UserID;
test.Firstname = RSAName.Firstname;
test.Surname = RSAName.Surname;
test.Document_Name = RSAName.Document_Name;
test.Document_URL = RSAName.URL;
test.UserType = RSAName.UserType;
test.Name = RSAName.PIN + RSAName.Document_Name;
}*/
return "success";
}//
public void SQLServiceStartForLog()
{
//BenefitDocModel rsapin = db.GetTable<BenefitDocModel>().FirstOrDefault(x => x.PIN == pin);
//cmd.Notification = null;
string connS = "Data Source=;Initial Catalog=ServiceTest;User ID=;password = ;Integrated Security=true";
SqlCommand cmd = new SqlCommand();
//cmd.Notification = null;
cmd = new SqlCommand("SELECT UserID, Surname, Firstname, PIN, URL, Document_Name FROM dbo.BenefitDoc");
cmd.CommandType = CommandType.Text;
SqlQueueWatcher = new SqlWatcher(connS, cmd, SqlWatcherNotificationType.Blocking);
SqlQueueWatcher.OnChange += new SqlWatcher.SqlWatcherEventHandler(QueueSQLWatcher_OnChangeForLog);
cmd.Notification = null;
SqlQueueWatcher.Start();
}
private void QueueSQLWatcher_OnChangeForLog(DataSet Result)
{
try
{
Console.WriteLine("Database monitoring is starting....");
benefitCheck();
Console.WriteLine("Database monitoring completed.");
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public void sendEmail(string pin)
{
MailMessage mail = new MailMessage("", "");
SmtpClient client = new SmtpClient();
client.Port = 25;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.Host = "smtp.gmail.com";
client.EnableSsl = true;
client.Credentials = new System.Net.NetworkCredential("", "");
mail.Subject = "New Record added for RSA with " + pin;
mail.Body = "The benefit application for user has been created.";
client.Send(mail);
}
public static void Stop()
{
SqlQueueWatcher.Dispose();
}
static void Main(string[] args)
{
Program n = new Program();
n.SQLServiceStartForLog();
Console.ReadLine();
}
}
}
That is not how SqlDependency works. Basically the way it works is you give it a query and if the query results change, it triggers a notification. But when you execute the datareader, it will not only return the changes. It returns data as if it was a regular query.
If you want to get only the changes, then you need to have a column in your table with something like LastModifiedDateTime and then query those records where LastModifiedDateTime is bigger than when you retrieved records the last time.
Alternatively, there is this NuGet package that will do this sort of thing for you if you are interested in using it.
Related
I have a method that check for records in a database and a timer that starts the method every 10 seconds. I check if a new record was inserted in a table and get these values to send emails.
The problem is, if has sended the email 1 time, it is no stop the timer and sends email every 10 seconds. To "solve" this i used an IF to check if the ID of the table was different, and partially i "resolved" the problem. And now, there is a new problem, because the result of the Select with joins query, returns much values and only the ID of that table is repeated, but the other fields are not, like this image:
As you can see, the ID of the table is 16, but the other ID are 2, 3, 4.
With my first solution, only sends email to the first row and ignore the others rows. Thats my problem, because i need to sends emails to the other rows. How can i do that?
This is my code (i use Windows Service):
public partial class GaxTankAlerts : ServiceBase
{
private string conn = "Data Source=.;Initial Catalog=DBCatalog;Integrated Security=false;User ID=GAX;Password=****;";
private Timer scheduleTimer = null;
private bool bandera;
private string id = "";
private string estatusAlerta = "";
private DateTime fechaAlerta;
public GaxTankAlerts()
{
InitializeComponent();
if (!EventLog.SourceExists("AlertService"))
{
EventLog.CreateEventSource("AlertService", "AlertLog");
}
eventLogEmail.Source = "AlertService";
eventLogEmail.Log = "AlertLog";
scheduleTimer = new Timer();
scheduleTimer.Interval = 10000;
scheduleTimer.Elapsed += new ElapsedEventHandler(scheduleTimer_Elapsed);
}
protected override void OnStart(string[] args)
{
bandera = true;
scheduleTimer.Start();
eventLogEmail.WriteEntry("El servicio ha iniciado");
//GetAlerts();
}
protected void scheduleTimer_Elapsed(object sender, ElapsedEventArgs e)
{
//if (bandera == true) {
// GetAlerts();
// //lastRun = DateTime.Now;
// bandera = false;
//}
eventLogEmail.WriteEntry("Comprobando si hay registros nuevos...");
if (bandera == true)
{
GetAlerts();
}
}
public void GetAlerts()
{
var path = AppDomain.CurrentDomain.BaseDirectory + "EmailTemplate\\Email.html";
string body = File.ReadAllText(path);
try
{
using (SqlConnection con = new SqlConnection(conn))
{
SqlCommand cmd = new SqlCommand("[General].[GetAlertas]", con);
cmd.CommandType = CommandType.StoredProcedure;
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
{
if (dr.HasRows)
{
while (dr.Read())
{
if (dr["ID"].ToString() != id)
{
id = dr["ID"].ToString();
if (dr["EstatusAlerta"].ToString() != estatusAlerta)
{
estatusAlerta = dr["EstatusAlerta"].ToString();
using (MailMessage mm = new MailMessage())
{
//Sends emails
}
}
}
//if (dr["EstatusAlerta"].ToString() != idReg)
//{
// idReg = dr["EstatusAlerta"].ToString();
// bandera = true;
//}
//else {
// bandera = false;
//}
}
}
}
dr.Close();
con.Close();
}
}
catch (Exception ex)
{
eventLogEmail.WriteEntry(ex.Message.ToString());
}
}
Thank you.
I have just started usingSignalR and setup configurations according to different articles and multiple questions here at SO. I have followed every step. I am unable to figure out why dependency OnChange is not firing ?
[HubName("broadcastHub")]
public class BroadcastHub : Hub
{
[HubMethodName("sendNotifications")]
public Task<object> SendNotifications()
{
DataTable dt = new DataTable();
using (var connection = new SqlConnection(strConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand(query, connection))
{
command.Notification = null;
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
var reader = command.ExecuteReader();
dt.Load(reader);
connection.Close();
}
}
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<BroadcastHub>();
var json = Newtonsoft.Json.JsonConvert.SerializeObject(dt);
return (context.Clients.All.RecieveNotification(json));
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change)
{
SendNotifications();
}
}
}
It works fine for the first time and I get expected data. But when any change is made in Table it does not fire dependency_OnChange
I have also identified that Broker Service is enabled by using the following queries:-
select is_broker_enabled from sys.databases where name='msdb'
select is_broker_enabled from sys.databases where name='mydb'
Both are enabled and value is 1.
Query which I am using in SendNotifications is:-
select Id,OXEName,OXEIP IP,ConnectionStatus Status, Case WHEN ConnectedOxeIP IS NULL OR ConnectedOxeIP = '' THEN OXEIP ELSE ConnectedOxeIP END as ConnectedOxeIP from PBXDetail
Java Script
$(function () {
var notifications = $.connection.broadcastHub;
notifications.client.recieveNotification = function (response) {
};
$.connection.hub.start().done(function () {
notifications.server.sendNotifications();
}).fail(function (e) {
});
});
Startup.cs
[assembly: OwinStartup(typeof(myNameSpace.Startup))]
namespace myNameSpace
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR(new HubConfiguration() { EnableJSONP = true });
}
}
}
Global.asax
protected void Application_Start(object sender, EventArgs e)
{
System.Data.SqlClient.SqlDependency.Start(strConnectionString);
}
protected void Application_End(object sender, EventArgs e)
{
System.Data.SqlClient.SqlDependency.Stop(strConnectionString);
}
I have figured it out and posting it as an answer so that any future reader who will be facing this type of issue would be able to figure it out.
I debugged piece of code and found that I was getting following Parameters with Values in SqlNotificationEventArgs at dependency_OnChange and those were:
Info => Invalid
Type => Subscribe
Source => Statement
If info is invalid this lead me to know that there was a problem with my query. Then I changed my query syntax like following and it worked fine.
select [Id],[OXEName],[OXEIP] as [IP],[ConnectionStatus] as [Status], Case WHEN [ConnectedOxeIP] IS NULL OR [ConnectedOxeIP] = '' THEN [OXEIP] ELSE [ConnectedOxeIP] END as [ConnectedOxeIP] from dbo.PBXDetail
Following are the query statuses which I found:
select * from table // did not work
select ID from table // did not work
select [ID] from table // did not work
select [ID] from dbo.table // Worked
After doing this I have found that at every page refresh dependency_OnChange was firing as many times the page was refresh. For instance if page is refreshed 10 times it will fire 10 times. So I have made the following changes:
[HubMethodName("sendNotifications")]
public Task<object> SendNotifications()
{
DataTable dt = new DataTable();
using (var connection = new SqlConnection(strConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand(query, connection))
{
command.Notification = null;
if (ServiceController.dependency == null)
{
ServiceController.dependency = new SqlDependency(command);
ServiceController.dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
}
var reader = command.ExecuteReader();
dt.Load(reader);
connection.Close();
}
}
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<BroadcastHub>();
var json = Newtonsoft.Json.JsonConvert.SerializeObject(dt);
return (context.Clients.All.RecieveNotification(json));
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change)
{
if (ServiceController.dependency != null)
{
ServiceController.dependency.OnChange -= dependency_OnChange;
ServiceController.dependency = null;
}
SendNotifications();
}
}
ServiceController
public static class ServiceController
{
internal static SqlCommand command = null;
internal static SqlDependency dependency = null;
internal static bool isCachingEnabled = false;
}
Global.asax
protected void Application_Start(object sender, EventArgs e)
{
if (!ServiceController.isCachingEnabled)
{
SqlDependency.Stop(strConnectionString);
SqlDependency.Start(strConnectionString);
}
}
I'm using a windows service for my online recharge website.
I'm selecting requested numbers from table and send it through api and get response. But some times its send request twice for same number while my table contains only one entry for that number.
My full page code is given below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Configuration;
using System.Net;
namespace bulkRechargeService
{
public partial class bulkRecharge : ServiceBase
{
System.Timers.Timer timer;
SqlConnection conn;
public bulkRecharge()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
proccessQue();
}
protected override void OnStop()
{
timer.Stop();
timer.Enabled = false;
}
protected void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
proccessQue();
}
public void proccessQue()
{
try
{
timer = new System.Timers.Timer();
timer.Interval = (1000) * 10;
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
conn = new SqlConnection(ConfigurationManager.AppSettings["ConnString1"]);
SqlDataAdapter adap = new SqlDataAdapter("SELECT * FROM recharge_request WHERE is_done=0 AND rdate>DATEADD(minute,-5,GETDATE())", conn);
DataTable dt = new DataTable();
adap.Fill(dt);
for (int i = 0; i < dt.Rows.Count; i++)
{
string rId = dt.Rows[i]["id"] + "";
string operators = dt.Rows[i]["operator"] + "";
string mobileNo = dt.Rows[i]["mobile_no"] + "";
string amount = dt.Rows[i]["amount"] + "";
string rechargeType = dt.Rows[i]["recharge_type"] + "";
string referenceId = dt.Rows[i]["user_reference_id"] + "";
string api = "http://*******************************************";
HttpWebRequest httpreq = (HttpWebRequest)WebRequest.Create(api);
HttpWebResponse httpres = (HttpWebResponse)httpreq.GetResponse();
StreamReader sr = new StreamReader(httpres.GetResponseStream());
string results = sr.ReadToEnd();
sr.Close();
SqlCommand cmd = new SqlCommand("UPDATE recharge_request SET is_done=1,rdate=GETDATE(),udate=GETDATE() WHERE id=" + rId, conn);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
timer.Enabled = true;
timer.Start();
}
catch(Exception ex)
{
}
}
}
}
Any ideas on where I'm going wrong?
I think your for loop it self runs more than one time even if you have one record in the table.
you started i =0 so put a minus (-1)
for (int i = 0; i < dt.Rows.Count - 1; i++)
instead of
for (int i = 0; i < dt.Rows.Count; i++)
protected override void OnStart(string[] args)
{
this.timer = new System.Timers.Timer(10000D);
this.timer.AutoReset = true;
this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
this.timer.Start();
}
protected override void OnStop()
{
this.timer.Stop();
this.timer = null;
}
protected void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
this.proccessQue();
}
I have place timer constructor in onStart method and remove from processQue method and now its works fine
I had a requirement to disable Copy Paste and even the print screen key while a website is running. So I wrote a WPF application to keep clearing the clipboard when Open Website link is clicked and stop clearing as soon as Close website button. But the problem is that when I press Open Website button the outlook client becomes very slow and sometimes unresponsive. I know that it has something to do with the clipboard only. Is there a way to disable Outlooks clipboard until the button is pressed.
However the code is not required but is included bleow, or can be downloaded from Dropbox:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Security.Cryptography;
using MySql.Data.MySqlClient;
using System.Threading;
using System.Net.NetworkInformation;
namespace ccb
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
string docNum,qs;
int status = 0;
static string connectionstring = "SERVER=abcd.com;port=3306;DATABASE=abcd_secure;UID=abcd_sec;PASSWORD=abcd_sec";
MySqlConnection conn = new MySqlConnection(connectionstring);
private static Random random = new Random((int)DateTime.Now.Ticks);
public MainWindow()
{
InitializeComponent();
}
private string RandomString(int size)
{
StringBuilder builder = new StringBuilder();
char ch;
for (int i = 0; i < size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
builder.Append(ch);
}
return builder.ToString();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
status = 1;
Thread backgroundThread = new Thread(clear);
backgroundThread.IsBackground = true;
backgroundThread.SetApartmentState(ApartmentState.STA);
backgroundThread.Start();
qs=generaterandomnumber();
insert(qs);
System.Diagnostics.Process.Start("http://abcd/login.php?osid=win&id="+qs);
}
private void clear()
{
while (status == 1)
System.Windows.Clipboard.Clear();
}
//Genrate random number and encrypt it to MD5
private string generaterandomnumber()
{
string Rand1 = RandomString(8);
string Rand2 = RandomString(8);
docNum = Rand1 + "-" + Rand2;
MD5 md5 = new MD5CryptoServiceProvider();
md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(docNum));
//get hash result after compute it
byte[] result = md5.Hash;
StringBuilder strBuilder = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
//change it into 2 hexadecimal digits
//for each byte
strBuilder.Append(result[i].ToString("x2"));
}
return strBuilder.ToString();
}
//Insert the generated value to the database
protected void insert(string q)
{
try
{
conn.Open();
string ins = "insert into mgen_validation_check(md5values) values(#m)";
MySqlCommand cmd = new MySqlCommand(ins, conn);
cmd.Parameters.AddWithValue("#m", q);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
}
private void button2_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Process.Start("http://abcd/include/LogoutPage.php");
this.Close();
status = 0;
try
{
conn.Open();
string del = "delete from mgen_validation_check where md5values=#m";
MySqlCommand cmd2 = new MySqlCommand(del, conn);
cmd2.Parameters.AddWithValue("#m", qs);
cmd2.ExecuteNonQuery();
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
}
private void Window_Closed(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("http://abcd/include/LogoutPage.php");
try
{
conn.Open();
string delconf = "delete from mgen_validation_check where md5values=#m";
MySqlCommand cmd3 = new MySqlCommand(delconf, conn);
cmd3.Parameters.AddWithValue("#m", docNum);
cmd3.ExecuteNonQuery();
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
}
}
}
The app is working properly except when running outlook becomes very slow. Other ms office apps are working properly.
Any help would be helpful.
Thanks in advance
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO.Ports;
using System.Threading;
using System.Windows.Threading;
using System.Data.SQLite;
namespace Datalogging
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public class ThreadExample
{
public static void ThreadJob(MainWindow mainWindow)
{
string dBConnectionString = #"Data Source = C:\Users\johnmark\Documents\Visual Studio 2012\Projects\SerialTrial\SerialTrial\bin\Debug\employee.sqlite;";
SQLiteConnection sqliteCon = new SQLiteConnection(dBConnectionString);
//open connection to database
try
{
sqliteCon.Open();
SQLiteCommand createCommand = new SQLiteCommand("Select empID from EmployeeList", sqliteCon);
SQLiteDataReader reader;
reader = createCommand.ExecuteReader();
//richtextbox2.Document.Blocks.Clear();
while (reader.Read())
{
string Text = (String.Format("{0}", Object.Equals(definition.buffering, reader.GetValue(0))));
if (Convert.ToBoolean(Text))
{
mainWindow.SerialWrite('s');
Console.WriteLine(Text);
//richtextbox1.Document.Blocks.Add(new Paragraph(new Run(Text)));
}
}
sqliteCon.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
public partial class MainWindow : Window
{
//string received_data;
//Thread readThread = new Thread(Read);
FlowDocument mcFlowDoc = new FlowDocument();
Paragraph para = new Paragraph();
SerialPort serial = new SerialPort();
public MainWindow()
{
InitializeComponent();
combobox1.Items.Insert(0, "Select Port");
combobox1.SelectedIndex = 0;
string[] ports = null;
ports = SerialPort.GetPortNames();
// Display each port name to the console.
int c = ports.Count();
for (int i = 1; i <= c; i++)
{
if (!combobox1.Items.Contains(ports[i - 1]))
{
combobox1.Items.Add(ports[i - 1]);
}
}
}
private void combobox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
private void Button_Click(object sender, RoutedEventArgs e)
{
try
{
if ((string)button2.Content == "Connect")
{
string myItem = combobox1.SelectedItem.ToString();
if (myItem == "Select Port")
{
MessageBox.Show("Select Port");
}
else
{
serial.PortName = myItem;
serial.Open();
button2.Content = "Disconnect";
textbox2.Text = "Serial Port Opened";
serial.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(port_DataReceived);
}
}
else
{
serial.Close();
button2.Content = "Connect";
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
#region Receiving
public void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int bytes = serial.BytesToRead;
byte[] buffer = new byte[bytes];
serial.Read(buffer, 0, bytes);
foreach (var item in buffer)
{
Console.Write(item.ToString());
}
definition.buffering = BitConverter.ToInt64(buffer, 0);
Console.WriteLine();
Console.WriteLine(definition.buffering);
Console.WriteLine();
Thread thread = new Thread(new ThreadStart(ThreadExample.ThreadJob(this)));
thread.Start();
thread.Join();
}
#endregion
public void WriteSerial(string text)
{
serial.Write(text);
}
}
}
Hi guys. Can anyone help me what went wrong in this code? It is displaying this error:
Error 2 'Datalogging.MainWindow' does not contain a definition for 'SerialWrite' and no extension method 'SerialWrite' accepting a first argument of type 'Datalogging.MainWindow' could be found (are you missing a using directive or an assembly reference?)
Error 3 Method name expected
how can I fix that? Please edit the code and post it here as your answer thanks.
Change your method call mainWindow.SerialWrite('s'); to mainWindow.WriteSerial('s'); to fit the method name declared here :
public void WriteSerial(string text)
You inverted both words.
For your "Method name expected", I guess it's in port_DataReceived. You need to pass a delegate to the thread, but you're not doing it correctly.
Instead of
Thread thread = new Thread(new ThreadStart(ThreadExample.ThreadJob(this)));
(you can't directly pass a method as a parameter, you can only use function pointers) you can use this syntax to pass a delegate :
Thread thread = new Thread(new ThreadStart(() => ThreadExample.ThreadJob(this)));
Please note that new TreadStart is redundant, new Thread(() => ThreadExample.ThreadJob(this)); will do the job.