I have below code which will run for infinite time period but I'm going to take time as input from user.
So if user enter 15mits I want to run this code for 15 mits.
Yes I can compare the DateTime.Now with 15mits but is there any other efficient way to do so ? As this will be my multi threading application.
private static async void SendDeviceToCloudMessagesAsync(string deviceid , string deviceKey)
{
deviceClient = DeviceClient.Create("HOSTNAME", new DeviceAuthenticationWithRegistrySymmetricKey(deviceid, deviceKey), Microsoft.Azure.Devices.Client.TransportType.Mqtt);
double minTemperature = 20;
double minHumidity = 60;
int messageId = 1;
Random rand = new Random();
do
{
double currentTemperature = minTemperature + rand.NextDouble() * 15;
double currentHumidity = minHumidity + rand.NextDouble() * 20;
var telemetryDataPoint = new
{
messageId = messageId++,
deviceId = deviceid,
temperature = currentTemperature,
humidity = currentHumidity
};
var messageString = JsonConvert.SerializeObject(telemetryDataPoint);
var message = new Microsoft.Azure.Devices.Client.Message(Encoding.ASCII.GetBytes(messageString));
message.Properties.Add("temperatureAlert", (currentTemperature > 30) ? "true" : "false");
await deviceClient.SendEventAsync(message);
Console.WriteLine("{0} > Sending message: {1}", DateTime.Now, messageString);
await Task.Delay(1000);
} while (true);
}
You could check out System.Timers.Timer. You create an instance of it setting the interval in the constructor, then write a method to handle the Elapsed event.
// Create a timer with a two second interval.
var aTimer = new System.Timers.Timer(2000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += OnTimedEvent // Name this whatever you want and put code here;
aTimer.AutoReset = true;
aTimer.Enabled = true;
All you have to do now is write the Elapsed event handler... OnTimedEvent in this case. Note that this method must have this signature:
private static void Object source, ElapsedEventArgs e)
try to replace your code against
await Task.Delay(TimeSpan.FromSeconds(1000));
Related
I want to launch a method in a program every 12 hours.
What do I have to do ?
Do I have to use a Timer to doing this ?
I have this code :
aTimer = new System.Timers.Timer(1000); //One second, (use less to add precision, use more to consume less processor time
int lastHour = DateTime.Now.Hour;
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Start();
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
if(lastHour < DateTime.Now.Hour || (lastHour == 23 && DateTime.Now.Hour == 0))
{
lastHour = DateTime.Now.Hour;
YourImportantMethod(); // Call The method with your important staff..
}
}
Can I adapt it to launch my program every 12 hours ?
A simple solution with async/await:
private static async void RepeatedAction()
{
TimeSpan delay = TimeSpan.FromHours(12);
while (true)
{
await Task.Delay(delay);
YourImportantMethod();
}
}
Use System.Threading.Timer
var start = TimeSpan.Zero;
var period = TimeSpan.FromHours(12);
var timer = new System.Threading.Timer((e) =>
{
YourImportantMethod();
}, null, start, period);
You can use Cron Jobs for this situation
Here is url check and implement. In corn job you can set when your program run
I'd like to run a function every minute to achieve the following:
Run function every minute
Run MySQL command to get count
Store the count into a variable
Compare the result to old result every minute
Create an If statement if number is not same to previous number.
Here is what I have:
private void Method()
{
int count = int.MinValue;
int prev_count = int.MinValue;
while (true)
{
//Get count from MySQL table
using (var conn = new MySqlConnection(ConnectionString.ConnString))
{
conn.Open();
using (var cmd = new MySqlCommand("select count(*) from table;", conn))
{
count = (int)cmd.ExecuteNonQuery();
}
}
if (count != prev_count)
{
prev_count = count;
}
}
}
My question is - is the correct way of coding this to compare the old number to new number? and also, how can I make this function run every minute?
Here how to call an event hendeler to track each given time.
Hope this will help you.
private static System.Timers.Timer timer;
private static void YourFunction(object sender, EventArgs e)
{
timer.Stop();
Console.WriteLine("Hello World!");
timer.Start();
}
static void Main(string[] args)
{
timer = new System.Timers.Timer();
timer.Interval = 5000; // time to configure
timer.Elapsed += new System.Timers.ElapsedEventHandler(YourFunction);
timer.Enabled = true;
timer.Start();
Console.ReadKey();
}
private void btnTestConcatenations_Click(object sender, EventArgs e)
{
var testTimer = new Stopwatch();
testTimer.Start();
testTimer.Stop();
var elapsedTime = testTimer.Elapsed;
var strTest = string.Empty;
for (int loopcount = 0; loopcount < NUMBER_CONCATENATIONS_TO_PERFORM; loopcount++)
{
strTest += "Adding 20 caracters";
}
Application.DoEvents();
A stop watch is used to time operations. Since the only other thing happening in this method is the concatenation loop, is it safe to assume that's what you want to time?
If so, you would do something like this:
private void btnTestConcatenations_Click(object sender, EventArgs e)
{
var testTimer = new Stopwatch();
var strTest = string.Empty;
var numOperations = NUMBER_CONCATENATIONS_TO_PERFORM;
// Start the stopwatch
testTimer.Start();
// Do some operation that you want to measure
for (int loopcount = 0; loopcount < numOperations; loopcount++)
{
strTest += "Adding 20 characters";
}
// Stop the stopwatch
testTimer.Stop();
var elapsedTime = testTimer.Elapsed;
// Do something with the stopwatch results
MessageBox.Show($"It took {elapsedTime} seconds to do {numOperations} concatenations");
}
I have script for refresh network with object label and panel but in script using looping mode with 'for'. I want to this real time refresh for 1 sec or 5 sec but because using 'for' make this procces need more time and get stuck screen. how to make the solution more quickly and in real time?
Thanks
public PosPing()
{
InitializeComponent();
RefreshPOS.Tick += new EventHandler(CheckPOSUG);
RefreshPOS.Start();
}
private void CheckPOSUG(object sender, EventArgs e)
{
Panel[] panelUG = new Panel[]{pnlPOSUG1,pnlPOSUG2,pnlPOSUG3,pnlPOSUG4,pnlPOSUG5,pnlPOSUG6,pnlPOSUG7,pnlPOSUG8};
Label[] LabelUG = new Label[]{lblUG1,lblUG2,lblUG3,lblUG4,lblUG5,lblUG6,lblUG7,lblUG8};
Label[] lblSpdUG = new Label[] { lblSpdUG1, lblSpdUG2, lblSpdUG3, lblSpdUG4, lblSpdUG5, lblSpdUG6, lblSpdUG7, lblSpdUG8 };
for (int x = 0; x < 8;x++ )
{
string IP = "192.168.135.1" + (x + 1).ToString();
var ping = new Ping();
var reply = ping.Send(IP, 10 * 1000);
LabelUG[x].Text = "POSBMS10" + x.ToString();
if (reply.Status == IPStatus.Success)
{
lblSpdUG[x].Text = reply.RoundtripTime.ToString() + " " + "ms";
panelUG[x].BackColor = Color.FromName("Lime");
}
else
{
lblSpdUG[x].Text = "Nonaktif";
panelUG[x].BackColor = Color.FromName("ButtonHighlight");
}
}
}
Without a good, minimal, complete code example, it's hard to know for sure how to best answer your question. But it looks like you are trying to ping eight different servers, which are represented by eight set of controls in your form.
If that is correct, then I agree with commenter Hans Passant that you should be using the SendPingAsync() method instead. This will allow you to execute the pings asynchronously, without blocking the UI thread, so that your program can remain responsive.
Because you are dealing with eight different servers, it makes sense to me that you should execute the eight pings asynchronously. To accomplish this, I would refactor the code a bit, putting the server-specific loop body into a separate method, so that each instance can be run concurrently.
Implementing it that way would look something like this:
private async void CheckPOSUG(object sender, EventArgs e)
{
Panel[] panelUG = new Panel[]{pnlPOSUG1,pnlPOSUG2,pnlPOSUG3,pnlPOSUG4,pnlPOSUG5,pnlPOSUG6,pnlPOSUG7,pnlPOSUG8};
Label[] LabelUG = new Label[]{lblUG1,lblUG2,lblUG3,lblUG4,lblUG5,lblUG6,lblUG7,lblUG8};
Label[] lblSpdUG = new Label[] { lblSpdUG1, lblSpdUG2, lblSpdUG3, lblSpdUG4, lblSpdUG5, lblSpdUG6, lblSpdUG7, lblSpdUG8 };
Task[] tasks = new Task[8];
for (int x = 0; x < 8; x++)
{
tasks[x] = PingServer(x, panelUG[x], LabelUG[x], lblSpdUG[x]);
}
try
{
await Task.WhenAll(tasks);
}
catch (Exception e)
{
// handle as appropriate, e.g. log and exit program,
// report expected, non-fatal exceptions, etc.
}
}
async Task PingServer(int index, Panel panel, Label ugLabel, Label spdLabel)
{
// NOTE: String concatenation will automatically convert
// non-string operands by calling calling ToString()
string IP = "192.168.135.1" + (index + 1);
var ping = new Ping();
var reply = await ping.SendPingAsync(IP, 10 * 1000);
ugLabel.Text = "POSBMS10" + x;
if (reply.Status == IPStatus.Success)
{
spdLabel.Text = reply.RoundtripTime + " ms";
// The Color struct already has named properties for known colors,
// so no need to pass a string to look Lime up.
panel.BackColor = Color.Lime;
}
else
{
spdLabel.Text = "Nonaktif";
panel.BackColor = Color.FromName("ButtonHighlight");
}
}
I have my own solution to import monthly sales data in my windows form application. When a user click on import button, the program is actually running but it looks like it's not responding. The process takes a long time about 5 minutes.
So, I'd like to implement a progress bar with status strip label to display as an user interface and let the users know how much the task is done. This is also my first time using a progress bar in my program. So, I read through some tutorials which show how to use it. Some people use progress bar with background worker and timer.
But I don't understand where I should use the solution that I have. In background worker DoWork() event? I don't want to fake it by abusing the progress bar like setting the progressBar.Maximum = 100, progressBar.Value = 0 and as long as the timer is ticking increasing the value by 5. The progress bar must report the actual progress while the program is running.
The following is the solution I am using now to import the data:
private void btnImport_Click(object sender, EventArgs e)
{
if (lsbxBrowsedFiles.Items.Count != 0)
{
ArrayList salesHeaderArr = new ArrayList();
ArrayList salesDetailArr = new ArrayList();
int i = 0;
while (i < browsedXmlFileList.Count)
{
if (browsedXmlFileList[i].ToUpper().EndsWith("SALESHEADER.XML"))
{
salesHeaderArr.Add(browsedXmlFileList[i]);
}
if (browsedXmlFileList[i].ToUpper().EndsWith("SALESDETAIL.XML"))
{
salesDetailArr.Add(browsedXmlFileList[i]);
}
i++;
}
if (selectedFileIsNotInDestinationFolder(salesHeaderArr, salesDetailArr) == true)
{
i = 0;
while (i < salesHeaderArr.Count)
{
SalesHeader salesHeader = new SalesHeader();
string sourceFilePath = salesHeaderArr[i].ToString();
readXMLFiles(sourceFilePath, SALES_HEADER);
SalesHeader salesCheck = (SalesHeader)salesHeaderList[0];
string checkOutletCode = salesCheck.OutletCode;
DateTime checkBusDate = salesCheck.BusinessDate.Value;
if (SalesHeader.IsThisRowAlreadyImportedInSalesHeader(checkOutletCode, checkBusDate) == false)
{
salesHeader.ImportSalesHeader(salesHeaderList);
salesHeader.CreateImportDataLog(getDestinationFilePath(sourceFilePath),
DateTime.Now, salesHeaderList.Count, SALES_HEADER);
}
else
{
string errorDate = checkBusDate.ToString("dd MMMM, yyyy");
MessageBox.Show("Selected XML File with BusinessDate: " + errorDate + " has been already imported.",
"ABC Cafe Import Sales Wizard");
MessageBox.Show("Please select a file which has not been imported!",
"ABC Cafe Import Sales Wizard");
return;
}
MoveXMLFiletoDestinationFolder(sourceFilePath);
i++;
}
i = 0;
while (i < salesDetailArr.Count)
{
SalesDetail salesDetail = new SalesDetail();
string sourceFilePath = salesDetailArr[i].ToString();
readXMLFiles(sourceFilePath, SALES_DETAIL);
SalesDetail salesCheck = (SalesDetail)salesDetailList[0];
string checkOutletCode = salesCheck.OutletCode;
DateTime checkBusDate = salesCheck.BusinessDate.Value;
if (SalesDetail.IsThisRowAlreadyImportedInSalesDetail(checkOutletCode, checkBusDate) == false)
{
salesDetail.ImportSalesDetail(salesDetailList);
salesDetail.GenerateCarryForward(salesDetailList);
salesDetail.CalculateImportInventoryBalance(salesDetailList);
salesDetail.CreateImportDataLog(getDestinationFilePath(sourceFilePath), DateTime.Now, salesDetailList.Count, SALES_DETAIL);
}
else
{
string errorDate = checkBusDate.ToString("dd MMMM, yyyy");
MessageBox.Show("Selected XML File with BusinessDate: " + errorDate + " has been already imported.",
"ABC Cafe Import Sales Wizard");
MessageBox.Show("Please select a file which has not been imported!",
"ABC Cafe Import Sales Wizard");
return;
}
MoveXMLFiletoDestinationFolder(sourceFilePath);
i++;
}
MessageBox.Show("Import has been successfully completed!",
"ABC Cafe Import Sales Wizard");
clearListBoxItems();
lblMessage.Visible = false;
}
//Abort the import operation here!
else
{
MessageBox.Show("Please select a file which has not been imported!",
"ABC Cafe Import Sales Wizard");
clearListBoxItems();
lblMessage.Visible = false;
}
}
else
{
MessageBox.Show("Please select XML files to import!",
"ABC Cafe Import Sales Wizard");
}
}
Any help will be very much appreciated!
This is how I have used Progress Bar in my application.
private void btnNext_Click(object sender, EventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.ProgressChanged += (se, eventArgs) => {
this.progressBar.Maximum = 100;
this.progressBar.Minimum = 0;
this.progressBar.Value = eventArgs.ProgressPercentage;
lblStatus.Text = eventArgs.UserState as String;
lblPercentage.Text = String.Format("Progress: {0} %", eventArgs.ProgressPercentage);
};
worker.DoWork += (se, eventArgs) => {
int progress = 0;
((BackgroundWorker)se).ReportProgress(progress, "Initializing the files...");
//Process that takes a long time
//Formula to calculate Progress Percentage
//This is how I calculated for my program. Divide 100 by number of loops you have
int findPercentage = ((i + 1) * 100) / salesHeaderArr.Count;
progress = 0;
progress += findPercentage / 2;
//Report back to the UI
string progressStatus = "Importing Sales Header... (" + getSourceFileName(sourceFilePath) + ")";
((BackgroundWorker)se).ReportProgress(progress, progressStatus);
//After Iterating through all the loops, update the progress to "Complete"
((BackgroundWorker)se).ReportProgress(100, "Complete...");
};
worker.RunWorkerCompleted += (se, eventArgs) =>
{
//Display smth or update status when progress is completed
lblStatus.Location = new Point(20, 60);
lblStatus.Text = "Your import has been completed. \n\nPlease Click 'Finish' button to close the wizard or \n'Back' button to go back to the previous page.";
lblPercentage.Visible = false;
progressBar.Visible = false;
btnBack.Enabled = true;
btnFinish.Enabled = true;
};
worker.RunWorkerAsync();
}
Your program has many loops,since it will be difficult to get the increment value and increment the progress bar value in each loop iteration.You could set the progress bar maximum to 100,Then divide 100 by the number of loops you have say X.
So the trick would be to fill the progress bar by this value when each loops completes
and yes you should put this code in backgroundworker's DoWork() otherwise it will freeze the form.Also there is no need for a timer.
You can use a ManualResetEvent, Now while you are processing, let the Progressbar Increase until it meets a certain point and wait for a Set.
Example:
you have this 2 fields
private int progress = 0;
private ManualResetEvent reset = new ManualResetEvent(false);
// Sets it to unsignalled
private ManualResetEvent reset2 = new ManualResetEvent(false);
while(progress < 40)
{
progress ++;
}
reset.WaitOne();
while(progress < 90)
{
progress ++;
}
reset2.WaitOne();
while(progress < 100)
{
progress ++;
}
// This finishes the progress, Now on your actual Work, you have to signal those wait.
DoWork()
{
// long process here. . . .
reset.Set();
// Another long process
reset2.Set();
}