How to set interval and loop sending data to database - c#

I have problems with my code. I'm trying to send one data to db every loop. Loop function working fine, but the data is not the latest. Its the 1st data I manage to send. so, my db is full of the same data. Here is my code:
private void timer1_Tick(object sender, EventArgs e)
{
int iIdx;
int[] iData;
bool[] bData;
//float[] irData;
if (m_bRegister) // Read registers (4X references)
{
// read register (4X) data from slave
if (adamTCP.Modbus().ReadHoldingRegs(m_iStart, m_iLength, out iData))
//if (adamTCP.Modbus().ReadInputRegs(m_iStart, m_iLength, out iData)) // Read registers (3X references)
{
m_iCount++; // increment the reading counter
txtStatus.Text = "Read registers " + m_iCount.ToString() + " times...";
// update ListView
for (iIdx = 0; iIdx < m_iLength; iIdx++)
{
listViewModbusCur.Items[iIdx].SubItems[2].Text = iData[iIdx].ToString(); // show value in decimal
listViewModbusCur.Items[iIdx].SubItems[3].Text = iData[iIdx].ToString("X04"); // show value in hexdecimal
}
//display label and send to DB
label1.Text = HttpGet("http://XXX.XXX.XXX.XXX/misc/api.php?station=KL&value=" + iData[2].ToString());
}
else
txtStatus.Text = "Read registers failed!"; // show error message in "txtStatus"
}
The "label1.text = httpGet" code is the one i'm trying to send data to. And I want to set 1 minute interval for the data send.

Related

C# Data Entry Threading From server response event

I have a functioning program that will calls for specific data from server, then when data is recieved it parses the data to add to the correct database row. the call when recieved data is landed is as followed:
public void AddData(string data)
{
if (this.ResponseData.InvokeRequired)
BeginInvoke(new AddDataDelegate(AddData), new object[] { data });
else
{
//sets new event args and object to run method
object sender = new object();
DoWorkEventArgs e = new DoWorkEventArgs(data);
//Calls the parsing and correct data row input
DataUpdate(data);
SystemGrid.Update();
}
}
My parsing coding is as followed:
private void DataUpdate(string e)
{
string[] data = e.ToString().Split(new string[] { "," }, StringSplitOptions.None);
if(data[0] == "[Q]")
{
int rowindex = 0;
if(data[2] == "ATQuoteFieldLastPrice")
{
foreach (DataGridViewRow Row in SystemGrid.Rows)
{
if (data[1] == Row.Cells[0].Value.ToString())
{
rowindex = Row.Index;
break;
}
}
SystemGrid.Rows[rowindex].Cells[5].Value = data[3];
}
}
if(data[0] == "[B]")
{
int index = 0;
foreach (DataGridViewRow Row in SystemGrid.Rows)
{
if (Row.Cells[0].Value.ToString() == data[1])
{
index = Row.Index;
break;
}
}
SystemGrid.Rows[index].Cells[9].Value = data[3];
SystemGrid.Rows[index].Cells[10].Value = data[4];
SystemGrid.Rows[index].Cells[11].Value = data[5];
SystemGrid.Rows[index].Cells[12].Value = data[6];
SystemGrid.Rows[index].Cells[13].Value = data[7];
}
}
when a timer goes off it sends for a set of data that arrives string by string.
first set finishes within 30 seconds. then the second set fires off, this takes 2min 20secs - 2min 30secs to finish. this second set has over 300,000 lines of data to go through. and will change on ever second set depending on what data changed on the server.
the third set finishes within 30secs
the fourth same as the second set
fith same as first.
6th set same as second set.
total time to update is right at 8 min give or take a little.
is there a way to thread the ADD(data) event safely, without data loss.
i've tried a backgroundworker, but the speed at which the data comes in is to fast so with that route it took the same time to finish. if tried a thread loop between 2 backgrounders, but continuely lost data.
is there a way to possibly thread pool this event upon landing, without loosing data. As the data will consistently coming in.
I am trying to get cut at least 3min of data processing.
so by the time the next update comes out the program is ready to fire again.

How to exit or close the application after x second in C#?

Actually I found something simmilar in stackoverflow, and it didn't work for me. They wanted to exit their application in a given time (23:00). I want to exit it after 3000 second. For me the answer was helpful, now it's working, the main point, that it's important, where you put this code in your programme.
This code is managing a multi beam RFID reader to localizate the Tags. It will give you the x and y coordinates ( and some other informations - EPC, Timestamp, the report type, etc). Actually the program works properly, but I would like to run it just for 5 minutes. I'm measuring the accuracy of the Reader, with different set up and it would be more comparable if all of my measurements would be 3000 sec ( or whatever) . Now the program exit if I hit the enter.
I was searching and trying a lot, but it doesn't want to work for me. I hope somebody can help here.
Here is the code:
using System;
using Impinj.OctaneSdk;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace OctaneSdkExamples
{
class Program
{
// Create an instance of the ImpinjReader class.
static ImpinjReader reader = new ImpinjReader();
static void Main(string[] args)
{
try
{
// Connect to the reader.
// Change the ReaderHostname constant in SolutionConstants.cs
// to the IP address or hostname of your reader.
reader.Connect(SolutionConstants.ReaderHostname);
// Assign the LocationReported event handler.
// This specifies which method to call
// when a location report is available.
reader.LocationReported += OnLocationReported;
// Get the default settings
// We'll use these as a starting point
// and then modify the settings we're
// interested in.
Settings settings = reader.QueryDefaultSettings();
// Put the xArray into location mode
settings.SpatialConfig.Mode = SpatialMode.Location;
// Enable all three report types
settings.SpatialConfig.Location.EntryReportEnabled = true;
settings.SpatialConfig.Location.UpdateReportEnabled = true;
settings.SpatialConfig.Location.ExitReportEnabled = true;
// Set xArray placement parameters
// The mounting height of the xArray, in centimeters
settings.SpatialConfig.Placement.HeightCm = 100
;
// These settings aren't required in a single xArray environment
// They can be set to zero (which is the default)
settings.SpatialConfig.Placement.FacilityXLocationCm = 0;
settings.SpatialConfig.Placement.FacilityYLocationCm = 0;
settings.SpatialConfig.Placement.OrientationDegrees = 0;
// Set xArray location parameters
settings.SpatialConfig.Location.ComputeWindowSeconds = 10;
settings.ReaderMode = ReaderMode.AutoSetDenseReader;
settings.Session = 2;
settings.SpatialConfig.Location.TagAgeIntervalSeconds = 20;
// Specify how often we want to receive location reports
settings.SpatialConfig.Location.UpdateIntervalSeconds = 5;
// Set this to true if the maximum transmit power is desired, false if a custom value is desired
settings.SpatialConfig.Location.MaxTxPower = false;
// If MaxTxPower is set to false, then a custom power can be used. Provide a power in .25 dBm increments
settings.SpatialConfig.Location.TxPowerInDbm = 23.00;
// Disable antennas targeting areas from which we may not want location reports,
// in this case we're disabling antennas 10 and 15
List<ushort> disabledAntennas = new List<ushort> { };
settings.SpatialConfig.Location.DisabledAntennaList = disabledAntennas;
// Uncomment this is you want to filter tags
/*
// Setup a tag filter.
// Only the tags that match this filter will respond.
// We want to apply the filter to the EPC memory bank.
settings.Filters.TagFilter1.MemoryBank = MemoryBank.Epc;
// Start matching at the third word (bit 32), since the
// first two words of the EPC memory bank are the
// CRC and control bits. BitPointers.Epc is a helper
// enumeration you can use, so you don't have to remember this.
settings.Filters.TagFilter1.BitPointer = BitPointers.Epc;
// Only match tags with EPCs that start with "3008"
settings.Filters.TagFilter1.TagMask = "3008";
// This filter is 16 bits long (one word).
settings.Filters.TagFilter1.BitCount = 16;
// Set the filter mode. Use only the first filter
settings.Filters.Mode = TagFilterMode.OnlyFilter1;
*/
// Apply the newly modified settings.
reader.ApplySettings(settings);
// Start the reader
reader.Start();
timer1_Tick(3000);
// Wait for the user to press enter.
Console.WriteLine("Press enter to exit");
Console.ReadLine();
// Apply the default settings before exiting.
reader.ApplyDefaultSettings();
// Disconnect from the reader.
reader.Disconnect();
}
catch (OctaneSdkException e)
{
// Handle Octane SDK errors.
Console.WriteLine("Octane SDK exception: {0}", e.Message);
}
catch (Exception e)
{
// Handle other .NET errors.
Console.WriteLine("Exception : {0}", e.Message);
}
}
// This event handler will be called when a location report is ready.
static void OnLocationReported(ImpinjReader reader, LocationReport report)
{
// Print out the report details
Console.WriteLine("Location report");
Console.WriteLine(" Type = {0}", report.ReportType);
Console.WriteLine(" EPC = {0}", report.Epc);
Console.WriteLine(" X = {0} cm", report.LocationXCm);
Console.WriteLine(" Y = {0} cm", report.LocationYCm);
Console.WriteLine(" Timestamp = {0} ({1})", report.Timestamp, report.Timestamp.LocalDateTime);
Console.WriteLine(" Read count = {0}", report.ConfidenceFactors.ReadCount);
// Saving data
string path = #"b:\Master Thesis\xArray\Tests\Test 3 - Height-100cm, Disabled Antennas - , TxPowerInDbm-23.25, UpdateIntervalSeconds-5, ComputeWindowSeconds-10, ReaderMode_AutoSetDenseReader, TagAgeIntervalSeconds-20, tags 40 cm from origo .txt";
if (!File.Exists(path))
{
using (StreamWriter sw = File.CreateText(path))
{
sw.WriteLine("Type, Epc, X Localization, Y localization, Timestamp, Local Date Time, Read Count ");
// This text is added only once to the file.
}
}
// This text is always added, making the file longer over time
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine(" {0} , {1} , {2} , {3} , {4} , {5} , {6} ", report.ReportType, report.Epc, report.LocationXCm, report.LocationYCm, report.Timestamp, report.Timestamp.LocalDateTime, report.ConfidenceFactors.ReadCount);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
reader.Disconnect();
}
}
}
If you just want your application to close after just 5 minutes you can do this:
static void Main()
{
System.Timers.Timer timer = new System.Timers.Timer(300000);
timer.Elapsed += Timer_Elapsed;
timer.Start();
//DO WHATEVER YOU WANT HERE
}
private static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Application.Exit();
}
I think your question is how to end a console application in a timer event handler. How about Environment.Exit(0).
public static void Main(String[] args)
{
Timer timer = new Timer();
timer.Interval = 10000;
timer.Elapsed += Timer_Elapsed;timer.Start();
Console.ReadKey();
}
private static void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
Environment.Exit(0);
}

Serial Port Data Received only working when breakpoint set C#

I'm trying to read data from serial port. It reads data when I set breakpoint.
I have tried with parent delegate invoke, some delay also. It doesn't work for me.
Here is my code
Read code from class file:
public void comport_DataReceived2(object sender, SerialDataReceivedEventArgs e)
{
var bytes = comport.BytesToRead;
var buffer = new byte[bytes];
string test2 = comport.ReadExisting();
if (IsReadPDSS)
{
if(test2 != string.Empty && test2 != " " && test2.Length > 30)
{
test2 = test2.Substring(30);
test2.Replace("000000000000P0000W", "");
strReceived += test2;
}
}
else
{
strReceived = test2;
}
}
windows form retriving read data :
string ss=FormObj.strReceived.ToString();
When you do application debugging, your system is not entirely frozen. Only the application you debug. Thus, while your app is in a breakpoint, incoming data on the serial port still is being accumulated.
The control flow is a bit fuzzy (probably because you changed it over a few times while looking for the problem). As it is written now, you read the data from the serial port whenever the event is raised. It is not likely that 30 bytes have arrived at the time you read the data. If you break into the debugger and do single stepping, it is rather more likely that you will find more than 30 bytes in the receive buffer (depending on what your device which transmits does).
Hence, a better way to write the control flow would look like this:
public void comport_DataReceived2(object sender, SerialDataReceivedEventArgs e)
{
var bytes = comport.BytesToRead;
if( bytes > 30 )
{
var test2 = comport.ReadExisting();
// additional testing code as required...
}
}
Depending on how the event raising behavior works, you might need to accumulate the data yourself in an extra buffer if the event is not getting re-raised after being fired for the first time... But that should be easy enough to test and adapt.

When event handler updates the content of a control? C#,WPF

I have this silly C# code on a buttonClick (WPF) handler and i wonder why the text box shows only the last value(=0) and no the previous values(9-1) . When I tested the code to a console application I saw all values in the command line.(I am beginner to C#,WPF)
Thnx
private void clock_Click(object sender, RoutedEventArgs e)
{
DateTime clicktime = DateTime.Now;
int nextsecont = DateTime.Now.Second + 1;
int now = clicktime.Second;
int timer = 10;
do
{
if (nextsecont == DateTime.Now.Second)
{
now++;
timer--;
nextsecont++;
textbox3.Text = timer.ToString();
}
} while (nextsecont <= (clicktime.Second + 10));
}
PS: I know there are better ways to do that (f.e. to use timer) but this is not the point.
Sorry for my english..
Explanation: now i see the initial value for 10 seconds and then i see the 0. I don't see intermediate values..
If you want all of the data to display in the textbox, you'll need to append the data to what is already in there.
textbox3.Text += " " + timer.ToString();
That will take what is in there, add a space, and then the timer.

Calling a javascript function asynchronosly from server side in c#

this is my code :
protected void BtnImport_Click(object sender, EventArgs e)
{
List<DataTable> tb = Helper.SplitTableToManyTables(FileTb, 50); // a list containing multiple DataTable each have 50 rows
int importedRowsCount = 0;
for (int KLoop = 0; KLoop < tb.Count; KLoop++)
{
...
if (QueriesDataHelper.ImportContacts(resTb, int.Parse(TxtHiddenGroupId.Value), Session))
{
importedRowsCount += resTb.Rows.Count;
var script = "DisplayProgressMsg(" + importedRowsCount + ")";
ScriptManager.RegisterStartupScript(this, GetType(), "MyScript", script, true);
if (KLoop == tb.Count - 1)
MessageBox.Show(importedRowsCount.ToString()+" Contacts imported successfully");
}
}
}
QueriesDataHelper.ImportContacts is a function that take a dataTable containing 50 rows and send it to a stored procedure
my problem is RegisterStartupScript is beeing executed after all the dataTables are beiing inserted i want to display a ms after the first DataTable finish tha
Ok,
Http is request/response protocol. But you want send do multiple responses for single request.
I see two ways for you. In both, you will have to run your long running process in separate thread. Then
1) use ajax, to ask server about progress every N seconds, and display result. Client's will track progress with some delay
2) web sockets(SignalR is great for such purposes). In this way you will be able to display progress in real time, but i think it's harder to implement

Categories